LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity/Fragment)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
- LiveData是一个数据持有者,给源数据包装一层。
- 源数据使用LiveData包装后,可以被observer观察,数据有更新时observer可感知。
- 但 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时,会遍历所有观察者
值唯一,会把最新值重现给订阅者,即粘性。
可被多个订阅者订阅(共享数据流)。
生产大于消费时,会丢失数据