Skip to content

Commit e6bd892

Browse files
committed
update
1 parent da95ba3 commit e6bd892

File tree

6 files changed

+258
-2
lines changed

6 files changed

+258
-2
lines changed

BasicKnowledge/Parcelable及Serializable.md

+62-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
Parcelable及Serializable
22
===
33

4+
5+
6+
### Serializable
7+
8+
在Java中Serializable接口是一个允许将对象转换为字节流(序列化)然后重新构造回对象(反序列化)的标记接口。
9+
10+
它会使用反射,并且会创建许多临时对象,导致内存使用率升高,并可能产生性能问题。
11+
12+
413
`Serializable`的作用是为了保存对象的属性到本地文件、数据库、网络流、`rmi`以方便数据传输,
514
当然这种传输可以是程序内的也可以是两个程序间的。而`Parcelable`的设计初衷是因为`Serializable`效率过慢,
615
为了在程序内不同组件间以及不同`Android`程序间(`AIDL`)高效的传输数据而设计,这些数据仅在内存中存在,`Parcelable`是通过`IBinder`通信的消息的载体。
@@ -11,6 +20,58 @@ Parcelable及Serializable
1120

1221
Parcelable不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
1322

23+
24+
### Parcelable实现
25+
26+
```kotlin
27+
data class Developer(val name: String, val age: Int) : Parcelable {
28+
29+
constructor(parcel: Parcel) : this(
30+
parcel.readString(),
31+
parcel.readInt()
32+
)
33+
34+
override fun writeToParcel(parcel: Parcel, flags: Int) {
35+
parcel.writeString(name)
36+
parcel.writeInt(age)
37+
}
38+
39+
// code removed for brevity
40+
41+
companion object CREATOR : Parcelable.Creator<Developer> {
42+
override fun createFromParcel(parcel: Parcel): Developer {
43+
return Developer(parcel)
44+
}
45+
46+
override fun newArray(size: Int): Array<Developer?> {
47+
return arrayOfNulls(size)
48+
}
49+
}
50+
}
51+
52+
```
53+
上面是实现Parcelable的代码,可以看到有很多重复的代码。
54+
为了避免写这些重复的代码,可以使用kotlin-parcelize插件,并在类上使用@Parcelize注解。
55+
56+
```kotlin
57+
@Parcelize
58+
data class Developer(val name: String, val age: Int) : Parcelable
59+
```
60+
61+
当在一个类上声明`@Parcelize`注解后,就会自动生成对应的代码。
62+
63+
64+
65+
66+
67+
Parcelable不会使用反射,并且在序列化过程中会产生更少的临时对象,这样就会减少垃圾回收的压力:
68+
69+
- Parcelable不会使用反射
70+
- Parcelable是Android平台特定的接口
71+
72+
所以Parcelable比Serializable更快。
73+
74+
1475
区别:
1576
- Parcelable is faster than serializable interface
1677
- Parcelable interface takes more time for implemetation compared to serializable interface
@@ -20,4 +81,4 @@ Parcelable不同于将对象进行序列化,Parcelable方式的实现原理是
2081

2182
----
2283
- 邮箱 :charon.chui@gmail.com
23-
- Good Luck!
84+
- Good Luck!

ImageLoaderLibrary/Glide简介(下).md

+27
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,33 @@ builder.setDiskCache(
420420
- `Disk cache needs to implement: DiskCache`
421421

422422

423+
424+
425+
Let's take Glide as an example. To optimize memory usage and use less memory, Glide does downsampling.
426+
427+
Downsampling means scaling the bitmap(image) to a smaller size which is actually required by the view.
428+
429+
Assume that we have an image of size 2000*2000, but the view size is 400*400. So why load an image of 2000*2000, Glide down-samples the bitmap to 400*400, and then show it into the view.
430+
431+
We use Glide like this:
432+
```
433+
Glide.with(fragment)
434+
.load(url)
435+
.into(imageView);
436+
```
437+
As we are passing the imageView as a parameter to the Glide, it knows the dimension of the imageView.
438+
439+
Glide down-samples the image without loading the whole image into the memory.
440+
441+
This way, the bitmap takes less memory, and the out-of-memory error is solved. Similarly, other Image Loading libraries like Fresco also do it.
442+
443+
This was all about how the Android Image Loading library optimizes memory usage.
444+
445+
446+
447+
448+
449+
423450
参考
424451
===
425452

Jetpack/ui/Jetpack Compose组件.md

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Jetpack Compose组件
2+
3+
### Text组件
4+
5+
```kotlin
6+
Text(text = "Hello World")
7+
Text(
8+
text = stringResource(id = R.string.next),
9+
style = TextStyle(
10+
fontSize = 25.sp,
11+
fontWeight = FontWeight.Bold,
12+
lineHeight = 35.sp,
13+
color = Color.Red,
14+
textDecoration = TextDecoration.LineThrough,
15+
fontStyle = FontStyle.Italic
16+
)
17+
)
18+
```
19+
20+
#### AnnotatedString多样式文字
21+
22+
在很多应用场景中,我们需要在一段文字中对局部内容应用特别格式以示突出,比如一个超链接或者一个电话号码等,此时需要用到AnnotatedString。AnnotatedString是一个数据类,除了文本值,它还包含了一个SpanStyle和ParagraphStyle的Range列表。SpanStyle用于描述在文本中子串的文字样式,ParagraphStyle则用于描述文本中子串的段落样式,Range确定子串的范围。
23+
24+
```kotlin
25+
val annotedText = buildAnnotatedString {
26+
withStyle(style = SpanStyle(fontSize = 23.sp)) {
27+
pushStringAnnotation(tag = "url", annotation = "https://www.baidu.com")
28+
append("haha")
29+
}
30+
31+
withStyle(SpanStyle(fontSize = 30.sp)) {
32+
append("A")
33+
}
34+
}
35+
36+
ClickableText(
37+
text = annotedText,
38+
onClick = { offset ->
39+
annotedText.getStringAnnotations(tag = "url", start = offset, end = offset)
40+
.firstOrNull()?.let {
41+
Log.e("@@@", it.item)
42+
}
43+
}
44+
)
45+
```
46+
47+
Compose提供了一种可点击文本组件ClickedText,可以响应我们对文字的点击,并返回点击位置。可以让AnnotatdString子串在相应的ClickedText中点击后,做出不同的动作。
48+
49+
50+
51+
52+
53+
### SelectionContainer
54+
55+
选中文字Text自身默认是不能被长按选择的,否则在Button中使用时,又会出现那种“可粘贴的Button”的例子。
56+
Compose提供了专门的SelectionContainer组件,对包裹的Text进行选中。可见Compose在组件设计上,将关注点分离的原则发挥到了极致。
57+
58+
59+
```kotlin
60+
SelectionContainer {
61+
Text("hahah")
62+
}
63+
```
64+
65+
66+
67+
### TextField输入框
68+
69+
70+
TextField有两种风格,一种是默认的,也就是filled,另一种是OutlinedTextField。
71+
```kotlin
72+
var text by remember { mutableStateOf("") }
73+
74+
TextField(value = text, onValueChange = {
75+
text = it
76+
}, label = { Text("请输入用户名") })
77+
```
78+
79+
这个text是一个可以变化的文本,用来显示TextField输入框中当前输入的文本内容。 在onValueChange回调中可以获取来自软键盘的最新输入,我们利用这个信息来更新可变状态text,驱动界面刷新显示最新的输入文本。
80+
81+
82+
***来自软键盘的输入内容不会直接更新TextField, TextField需要通过观察额外的状态更新自身,这也体现了声明式UI中“状态驱动UI”的基本理念。***
83+
84+
85+
86+
87+
88+
### Column组件
89+
90+
很多产品中都有展示一组数据的需求场景,如果数据数量是可以枚举的,则仅需通过Column组件来枚举列出。
91+
92+
93+
然而很多时候,列表中的项目会非常多,例如通讯录、短信、音乐列表等,我们需要滑动列表来查看所有的内容,可以通过Column的Modifier添加verticalScroll()方法来让列表实现滑动。
94+
95+
96+
#### LazyComposables
97+
98+
给Column的Modifier添加verticalScroll()方法可以让列表实现滑动。
99+
100+
但是如果列表过长,众多的内容会占用大量的内存。然而更多的内容对于用户其实都是不可见的,没必要记载到内存。
101+
102+
所以Compose提供了专门用于处理长列表的组件,这些组件指挥在我们能看到的列表部分进行重组和布局,它们分别是LazyColumn和LazyRow。其作用类似于传统视图中的ListView或者RecyclerView。
103+
104+
105+
106+

KotlinCourse/4.Kotlin_表达式&关键字.md

+36
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,42 @@ for(num in nums) {
218218

219219

220220

221+
### infix关键字
222+
223+
Kotlin中infix的中缀表示法允许在不使用点和括号的情况下调用函数。
224+
225+
226+
例如:
227+
228+
```kotlin
229+
infix fun Int.add(value: Int): Int = this + value
230+
231+
val sum = 5 add 10
232+
```
233+
234+
平时在使用map的时候经常会这样用:
235+
236+
```kotlin
237+
val map = mapOf(
238+
1 to "A",
239+
2 to "B",
240+
3 to "C"
241+
)
242+
```
243+
而mapOf需要一个Pair<K, V>的列表。这里可以使用to关键字来实现就是因为infix。
244+
245+
我们可以检查一下Kotlin中的Pair的源码,就会发现:
246+
```kotlin
247+
infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
248+
```
249+
250+
使用infix的时候有个点需要注意:
251+
252+
- 它必须是一个函数
253+
- 必须只有一个参数
254+
- 参数不能是可变参数
255+
- 参数不能有默认值
256+
221257

222258
- [上一篇:3.Kotlin_数字&字符串&数组&集合](https://github.com/CharonChui/AndroidNote/blob/master/KotlinCourse/3.Kotlin_%E6%95%B0%E5%AD%97%26%E5%AD%97%E7%AC%A6%E4%B8%B2%26%E6%95%B0%E7%BB%84%26%E9%9B%86%E5%90%88.md)
223259
- [下一篇:5.Kotlin_内部类&密封类&枚举&委托](https://github.com/CharonChui/AndroidNote/blob/master/KotlinCourse/5.Kotlin_%E5%86%85%E9%83%A8%E7%B1%BB%26%E5%AF%86%E5%B0%81%E7%B1%BB%26%E6%9E%9A%E4%B8%BE%26%E5%A7%94%E6%89%98.md)

KotlinCourse/5.Kotlin_内部类&密封类&枚举&委托.md

+21
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,27 @@ object Resource {
411411
}
412412
```
413413

414+
415+
Kotlin中除了object之外还有一个companion object,也可以替代Java中的static关键字,那他俩有什么区别呢?
416+
417+
418+
#### Companion object
419+
420+
- 必须在一个类中定义
421+
- companion object会在类第一次加载的时候就创建好,这就意味着我们可能还没使用的时候就初始化好了
422+
- 它等同于Java中的static
423+
- 如果我们不手动指定名字的话会有一个默认的Companion的名字
424+
- 在调用方法或变量的时候可以省略名字
425+
426+
#### object
427+
428+
- 可以被定义到任何地方
429+
- 在我们第一次使用它时才会创建。
430+
- 主要被用作提供单例行为
431+
- 必须提供一个命名
432+
- 如果在一个类中定义object,那在调用方法或者变量的时候不能省略名字
433+
434+
414435
### 对象表达式
415436

416437
对象也能用于创建匿名类实现。

MobileAIModel/TensorFlow Lite

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ TensorFlow Lite
66

77
[TensorFlow Lite](https://tensorflow.google.cn/lite?hl=zh-cn) 是一组工具,可帮助开发者在移动设备、嵌入式设备和 loT 设备上运行模型,以便实现设备端机器学习。
88

9+
10+
TensorFlow Lite是TensorFlow在手机和嵌入设备上的一个轻量级框架。
11+
912
主要特性:
1013

1114
- 通过解决以下 5 项约束条件,针对设备端机器学习进行了优化:延时(数据无需往返服务器)、隐私(没有任何个人数据离开设备)、连接性(无需连接互联网)、大小(缩减了模型和二进制文件的大小)和功耗(高效推断,且无需网络连接)。
@@ -16,7 +19,9 @@ TensorFlow Lite
1619

1720

1821
1. 创建 TensorFlow Lite 模型
19-
TensorFlow Lite 模型以名为 FlatBuffer 的专用高效可移植格式(由“.tflite”文件扩展名标识)表示。与 TensorFlow 的协议缓冲区模型格式相比,这种格式具有多种优势,例如可缩减大小(代码占用的空间较小)以及提高推断速度(可直接访问数据,无需执行额外的解析/解压缩步骤),这样一来,TensorFlow Lite 即可在计算和内存资源有限的设备上高效地运行。
22+
TensorFlow Lite 模型以名为 FlatBuffer 的专用高效可移植格式(由“.tflite”文件扩展名标识)表示。
23+
24+
与 TensorFlow 的协议缓冲区模型格式相比,这种格式具有多种优势,例如可缩减大小(代码占用的空间较小)以及提高推断速度(可直接访问数据,无需执行额外的解析/解压缩步骤),这样一来,TensorFlow Lite 即可在计算和内存资源有限的设备上高效地运行。
2025

2126
TensorFlow Lite 模型可以选择包含元数据,并在元数据中添加人类可读的模型说明和机器可读的数据,以便在设备推断过程中自动生成处理前和处理后流水线。如需了解详情,请参阅添加元数据。
2227

0 commit comments

Comments
 (0)