Jetpack之LiveData分析

分析:


LiveData本身是一个抽象类,在Jetpack组件中唯一的子类是MutableLiveData。公开了两个方法setValue和postValue。两个方法用来更新LiveData的值,前者只能在主线程中调用,后者可以在子线程中调用,通过Handler消息机制,通知到主线程更新。

在这分析这两个方法之前,先来看下,观察者如何订阅LiveData,即LiveData的observe方法:

// 第一个参数是Lifecycle的持有者,比如Activity、Fragment

// 第二个参数是观察者对象,我们一般就是直接创建一个匿名对象

public void observe(LifecycleOwner owner, Observer observer) {

// 如果观察者在订阅LiveData的时候已经处于destoryed状态,直接跳过订阅

if (owner.getLifecycle().getCurrentState() == DESTROYED) {

return;

}

// 将owner与observer封装成LifecycleBoundObserver对象,这个对象主要封装了

// 对Lifecycle的生命状态的赋值操作以及状态改变时对观察者进行取消订阅的操作。

LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

// mObservers是一个支持在迭代的过程中进行更改的链表结构(存放Entry<K,V>),

// 存放的是观察者和上面的包装对象,注意如果链表已经存放了某一个key为observer的entry

// 不是去更新这个entry而是直接返回value。

ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);

// 如果返回的value不是null,然后去确定一下,这个observer的owner与新传入的owner

// 是不是一致的,如果一致,就表示这个观察者已经绑定了某一个owner,不能重复绑定

if (existing != null && !existing.isAttachedTo(owner)) {

throw new IllegalArgumentException( “Cannot add the same observer”

  • " with different lifecycles" );

}

// 如果返回的value不是null,但是也没有进入上面的异常抛出

// 那就是这一次绑定的owner是一样的,没有必要重复绑定相同的owner

if (existing != null) {

return;

}

// 为owner添加生命周期观察者,这样wrapper,或者说observer就可以感知到

// owner(Activity/Fragment)的生命周期,当其生命周期发生变化的时候,

// 可以调用到wrapper的onStateChanged,去更新活跃状态

owner.getLifecycle().addObserver(wrapper);

}

LifecycleBoundObserver的onStateChanged方法:

public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {

// 如果组件的生命周期是销毁状态,那么会自动的removeObserver移除观察者,

// 从而解除observer对LifecyclerOwner的引用,避免内存泄露的发生

if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {

removeObserver(mObserver);

return;

}

// 如果不是Destoryed状态,那么当Owner的生命周期变化时,会去更新到LiveData的活跃状态

activeStateChanged(shouldBeActive());

}

上面是对LiveData的生命状态相关的分析,然后看下对LiveData的赋值操作。

setValue:

protected void setValue(T value) {

assertMainThread( “setValue” );// 非主线程IllegalStateException

mVersion++;// 标记当前data的版本

mData = value;// 赋值data

dispatchingValue(null);

}

setValue调用的dispatchingValue,传入的是null:

private void dispatchingValue(@Nullable ObserverWrapper initiator) {

// 如果正在分发value,则直接return

if (mDispatchingValue) {

mDispatchInvalidated = true;

return;

}

mDispatchingValue = true;

do {

mDispatchInvalidated = false;

if (initiator != null) {

// 后续

considerNotify(initiator);

initiator = null;

} else {

// 遍历mObservers链表,去决定是否需要通知观察者更新

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

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

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

if (mDispatchInvalidated) {

break;

}

}

}

} while (mDispatchInvalidated);

mDispatchingValue = false;

}

considerNotify:

private void considerNotify(ObserverWrapper observer) {

// 如果观察者不处于活跃状态,则直接跳过

if (!observer.mActive) {

return;

}

// 可能出现Owner的生命周期变化了,但是LiveData并没有收到相关通知,

// 这里主动去获取Owner的当前(最新)生命状态

// shouldBeActivie在这两种情况下返回true

// STARTED:对应的就是Activity生命周期的调用onStart之后,onPause之前

// RESUMED: onResume调用之后

if (!observer.shouldBeActive()) {

// 如果处于Owner的生命状态不活跃,这里更新下

observer.activeStateChanged(false);

return;

}

// 如果最新的数据版本不大于上一次变动的版本,就是没变化,那就直接return

if (observer.mLastVersion >= mVersion) {

return;

}

// 更新上一次变动的版本值

observer.mLastVersion = mVersion;

// 会掉到observer的onChanged方法,传入新的data

//也就是我们在订阅LiveData的时候,传入的匿名对象重写的onChanged方法

// 到这里,观察者就收到了LiveData的数据变动的通知。

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

}

postValue:

postValue用于在子线程通知主线程livedata发生了变化,代码如下:

protected void postValue(T value) {

boolean postTask;

synchronized (mDataLock) {

postTask = mPendingData == NOT_SET;

// mPendingData

mPendingData = value;

}

if (!postTask) {

return;

}

// 将mPostValueRunnable这个任务抛到主线程执行

ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);

}

先看下mPostValueRunnable:

private final Runnable mPostValueRunnable = new Runnable() {

@Override

public void run() {

// 在主线程中完成data的更新

Object newValue;

synchronized (mDataLock) {

文末

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

Android精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》
点击传送门,即可获取!

15665776606)]

【Android部分高级架构视频学习资源】

Android精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》
点击传送门,即可获取!

  • 25
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值