写点什么

Android mvvm 之 LiveData 的原理,2021 年 Android 高级面试题

用户头像
Android架构
关注
发布于: 1 小时前

LiveData 中更新 active 标记的方法:


boolean shouldBeActive() {


return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);


}


这说明,只有当 LifecycleOwner 的状态至少是 STARTED,LiveData 才是处于激活状态的。再看 Lifecycle.State 的枚举顺序:


public enum State {


DESTROYED,


INITIALIZED,


CREATED,


STARTED,


RESUMED;


/**


  • Compares if this State is greater or equal to the given {@code state}.

  • @param state State to compare with

  • @return true if this State is greater or equal to the given {@code state}


*/


public boolean isAtLeast(@NonNull State state) {


return compareTo(state) >= 0;


}


}


进一步说明,只有当 LifecycleOwner 的状态是 STARTED 和 RESUMED 时,LiveData 才是处于激活状态的,而只有在激活状态下,LiveData 才会将最新数据变化通知给它的订阅者:


private void considerNotify(ObserverWrapper observer) {


if (!observer.mActive) { // 没有激活,不进行通知


return;


}


// 在 LifecycleOwner 的生命周期变化事件分派之前,需要提前主动更新一下激活状态,


// 如果未激活,同样不进行通知


if (!observer.shouldBeActive()) {


observer.activeStateChanged(false);


return;


}


//...省略非关键代码


observer.mObserver.onChanged((T) mData);


}


严格的说这里并不应该叫 LiveData 的激活状态,而应该是向 LiveData 进行订阅的 LifecycleOwner 的激活状态,此时 LifecycleOwner 作为观察者观察 LiveData 的变化。所以这里可能叫 LiveData 在每一个 LifecycleOwner 上的分身的激活状态更合适,为了表述方便,我们就统称叫 LiveData 的激活状态。我们将在 2.2 节描述 LifecycleOwner 如何订阅 LiveData。


以上,只为了说明一个问题:LiveData 需要订阅 LifecycleOwner,感知其生命周期变化:



图示说明,LiveData 订阅 LifecycleOwner,而由 LifecycleOwner.Lifecycle 代理完成生命周期状态变化通知,所以 LiveData 直接能感知的是 Lifecycle。

[](

)2.2 LifecycleOwner 订阅数据变化


LifecycleOwner 在 STARTED 和 RESUMED 的状态下可以根据 LiveData 更新 UI 的状态,所以 LifecycleOwner 需要订阅 LiveData 的数据变化。


在实际实现当中,LifecycleOwner 作为抽象层并不具体负责订阅 LiveData,而是由业务层在 LifecycleOwner 中完成具体的订阅工作,此时我们称 LifecycleOwner 为 Controller 更合适,虽然它们往往是同一个东西:



注意图示,一个 User-defined Observer 必须和一个 LifecycleOwner 唯一绑定,否则将无法订阅。试想,如果一个 Observer 同时绑定两个 LifecycleOwner:L1 和 L2,假如 L1 处于 RESUMED 的状态,而 L2 处于 DESTROYED 的状态,那么 LiveData 将无所适从:如果遵循 L1 的状态,将变化通知给 Observer,则更新 L2 会出错;如果遵循 L2 的状态,不将变化通知给 Observer,则 L1 得不到及时更新。

[](

)2.3 多对多的双向订阅网


LiveData 和 LifecycleOwner 之间因为需要相互观察对方状态的变化,从而需要实现双向订阅;同时,为了支持良好的可扩展能力,各自都维护了一个观察者列表,形成一个多对多的双向订阅网络:



我们看到一个 LiveData 是可以同时向多个 LifecycleOwner 发起订阅的,所以,LiveData 本身其实并不实际维护一个激活状态,真正的激活状态维护在 LifecycleOwner 的 User-defined observer 中。

[](

)3 LiveData 的事件变化


LiveData 值更新之后的需要通知订阅者(观察者),其通知流程非常简单:



其中,判断观察者是否激活,即判断 LifecycleOwner 是否处于 STARTED 或 RESUMED 状态,在 2.1 节中已有说明。


我们看一下关键的源代码:


// 入口


@MainThread


protected void setVal


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ue(T value) {


// 必须在主线程调用


assertMainThread("setValue");


//..省略非关键代码


// 设置新值并派发通知


mData = value;


dispatchingValue(null);


}


// 通知派发流程


void dispatchingValue(@Nullable ObserverWrapper initiator) {


//..省略非关键代码


// 遍历观察者列表


for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =


mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {


// 尝试通知观察者


considerNotify(iterator.next().getValue());


//..省略非关键代码


}


}


其中 LiveData.considerNotify() 在 2.1 节中已有说明。

[](

)4 LifecycleOwner 的事件变化


对于 LifecycleOwner 来说,其变化的事件即为生命周期状态的变化。在 LifecycleOwner 的事件委托者 Lifecycle 看来,无论是发生了 ON_CREATE 事件还是 ON_START 事件,或是任何其它的事件,其事件的切换流程都是通用的。


换言之,只要 Lifecycle 接口的实现者实现这一通用切换流程,便只需给 LifecycleOwner 暴露一个切换入口,就能在 LifecycleOwner 的各个生命周期回调函数中调用这个入口就可以了。这样我们在 LifecycleOwner 中应该可以看到形如这样的流程(伪代码表示):


public class Activity/Fragment implements LifecycleOwner {


@Override


public onCrate() {


//...省略非关键代码


// 在 Jetpack 框架中,LifecycleImpl 被命名为 LifecycleRegistry


LifecycleImpl.handleLifecycleEvent(ON_CREATE);


}


@Override


public onStart() {


//...省略非关键代码


LifecycleImpl.handleLifecycleEvent(ON_START);


}


@Override


public onResume() {


//...省略非关键代码


LifecycleImpl.handleLifecycleEvent(ON_RESUME);


}


@Override


public onPause() {


//...省略非关键代码


LifecycleImpl.handleLifecycleEvent(ON_PAUSE);


}


@Override


public onDestroy() {


//...省略非关键代码


LifecycleImpl.handleLifecycleEvent(ON_DESTROY);


}


}


当然,在具体的源代码中,与上述伪代码会有一些出入,但是大体的结构是一致的。在 Jetpack 框架中,这个 Lifecycle 的实现者叫做 LifecycleRegistry。所以我们这里重点需要关注的就是 LifecycleRegistry 这个 Lifecycle 的代理接口的实现类是如何通知生命周期事件变化的。

[](

)4.1 Lifecycle 接口的实现——LifecycleRegistry

[](

)4.1.1 LifecycleRegistry 的订阅实现


如 2.2 节所述,通过 LiveData.observe(owner, user-defined observer),LifecycleOwner 的业务层向 LiveData 订阅数据变化,而在 LiveData.observe() 方法内,同时会自动通过 Lifecycle.addObserver(LiveData-defined observer) 向 LifecycleOwner 订阅生命周期变化:


// LiveData.observe()

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android mvvm 之 LiveData 的原理,2021年Android高级面试题