LiveData 的设计及常用用法。
| 关键词们 | 原理 |
|---|---|
| LiveData | 就是跟我们打交道的类 |
| Observer | 观察者,会通过 onChange 告知 Observer 数据的变化 |
| ObserverWrapper | LiveData 内部对 Observer 的包装,驱动 activeStateChanged 状态的变化 |
| mVersion | 当前数据版本的版本号,使用版本号达到粘性通知 |
| LifecycleOwner | 获取对应的 Lifecycle 根据这个去监听对应组件的生命周期 |
| LifecycleBoundObserver | 继承 ObserverWrapper 包装了对 state 的消费,判定是否可见去通知以及在 Destroy 的周期去移除对应的 Observer |
| 关键方法们 | 我们接触到的和常用的方法 |
| observe | 当前 lifecycle 的观察者,对数据的观察入口 |
| observeForever | 同上,只是永远监听无论是否可见,都返回 true ,实际上是对不同的封装 |
| postValue | 帮助我们在主线程里面更新数据 |
| setValue | 主线程更新数据,这里会驱动分发数据 |
| dispatchingValue | 分发数据根据 owner 的状态去判断是否分发数据 |
| considerNotify | 具体的通知动作,在 dispatching 里面调用 |
| onChange | 最终数据的到达 |
code 去解析流程:
// 首先是入口
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe"); // 必须在主线程调用
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
// 为 owner 添加 observer 驱动更新状态,实际上在 Activity 和 Fragment 里面是 LifecycleRegistry ,这里 Observer 会被包装为 ObserverWithState
owner.getLifecycle().addObserver(wrapper);
}
// LifecycleRegistry 内部调度 handleLifecycleEvent,根据当前 Event 推导下一个状态并且更新
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
// Fragment 或者 Activity 里面使用这个去驱动生命周期的变化,例如 onCreate onResume 等等
@Override
boolean shouldBeActive() {
// 这里实际上就是 LifecycleRegistry 的 getCurrnetState 去判断,这里的 State 是之前 Event 驱动的更新
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
总结
我们使用 LiveData 的便利之处就是为了他的通知以及生命感知能力,其实借助这些东西,我们也可以实现一些类似的架子,这里就是通过这些生命周期的阶段和状态,达到我们自己的自动化操作,例如在 onDestory 或者相应的周期去做一些自己的自动化操作,例如 EventBus 虽然好使但是他的生命感知为零,导致这个的全局使用会导致重构或者卸掉这些东西狠麻烦。有了生命感知,那么我们就可以去动态卸载了。