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) {

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
PENNXKGk-1715757301292)]

[外链图片转存中…(img-tcfWmgeQ-1715757301294)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值