Jetpack 之 LiveData

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity/Fragment)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。


  1. LiveData是一个数据持有者,给源数据包装一层。
  2. 源数据使用LiveData包装后,可以被observer观察,数据有更新时observer可感知。
  3. 但 observer的感知,只发生在(Activity/Fragment)活跃生命周期状态(STARTED、RESUMED)。
1
2
3
4
5
6
7
8
9
10
11
12
TestLifecycleActivity: onCreate: INITIALIZED
TestLifecycleActivity: ON_CREATE
TestLifecycleActivity: onStart: CREATED
TestLifecycleActivity: ON_START
TestLifecycleActivity: onResume: STARTED
TestLifecycleActivity: ON_RESUME / RESUMED
TestLifecycleActivity: ON_PAUSE
TestLifecycleActivity: onPause: STARTED
TestLifecycleActivity: ON_STOP
TestLifecycleActivity: onStop: CREATED
TestLifecycleActivity: ON_DESTROY
TestLifecycleActivity: onDestroy: DESTROYED
确保界面符合数据状态

当生命周期状态变化时,LiveData通知Observer,可以在observer中更新界面。观察者可以在生命周期状态更改时刷新界面,而不是在每次数据变化时刷新界面。

不会发生内存泄漏

observer会在LifecycleOwner状态变为DESTROYED后自动remove。

不会因 Activity 停止而导致崩溃

如果LifecycleOwner生命周期处于非活跃状态,则它不会接收任何 LiveData事件。

不需要手动解除观察

开发者不需要在onPause或onDestroy方法中解除对LiveData的观察,因为LiveData能感知生命周期状态变化,所以会自动管理所有这些操作。

数据始终保持最新状态

数据更新时 若LifecycleOwner为非活跃状态,那么会在变为活跃时接收最新数据。例如,曾经在后台的 Activity 会在返回前台后,observer立即接收最新的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_livedata)
Log.d(TAG, "onCreate: ")
MyLiveData.get().observe(this, {
Log.d(TAG, "MyLiveData onChanged : $it")
})
MyLiveData.get().value = "onCreate"
}

override fun onStart() {
super.onStart()
Log.d(TAG, "onStart: ")
MyLiveData.get().value = "onStart"
}

override fun onResume() {
super.onResume()
Log.d(TAG, "onResume: ")
MyLiveData.get().value = "onResume"
}

override fun onPause() {
super.onPause()
Log.d(TAG, "onPause: ")
MyLiveData.get().value = "onPause"
}

override fun onStop() {
super.onStop()
Log.d(TAG, "onStop: ")
MyLiveData.get().value = "onStop"
}

override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy: ")
MyLiveData.get().value = "onDestroy"
}

class MyLiveData : LiveData<String>() {

override fun onActive() {
super.onActive()
Log.d("TestLiveDataActivity", "-- onActive --")
}

override fun onInactive() {
super.onInactive()
Log.d("TestLiveDataActivity", "-- onInactive --")
}

public override fun setValue(value: String?) {
super.setValue(value)
}

companion object {
lateinit var sInstance: MyLiveData

@MainThread
fun get(): MyLiveData {
sInstance = if (this::sInstance.isInitialized) sInstance else MyLiveData()
return sInstance
}
}

}

TestLiveDataActivity: onCreate:
TestLiveDataActivity: onStart:
TestLiveDataActivity: -- onActive --
TestLiveDataActivity: MyLiveData onChanged : onStart
TestLiveDataActivity: onResume:
TestLiveDataActivity: MyLiveData onChanged : onResume
TestLiveDataActivity: onPause:
TestLiveDataActivity: MyLiveData onChanged : onPause
TestLiveDataActivity: -- onInactive --
TestLiveDataActivity: onStop:
TestLiveDataActivity: onDestroy:

LiveData原理是观察者模式

1
2
3
4
5
6
7
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
……
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
……
owner.getLifecycle().addObserver(wrapper);
}
1
2
3
4
5
6
7
8
9
10
11
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private abstract class ObserverWrapper {

void activeStateChanged(boolean newActive) {
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}

}
1
2
3
dispatchingValue
considerNotify
observer.mObserver.onChanged((T) mData);

LivaData数据更新可以使用setValue(value)、postValue(value),postValue(value)用于子线程

使用setValue()、postValue()更新数据时会通知回调所有的观察者,
因为内部调用dispatchingValue(null),传入null时,会遍历所有观察者

值唯一,会把最新值重现给订阅者,即粘性。

可被多个订阅者订阅(共享数据流)。

生产大于消费时,会丢失数据