用它的好处:①最重要的,LiveData作为被观察者可以感知到观察者(Activity/Fragment)的生命周期,自行去管理自身的生命周期。②如上说的,只有当Activity或者Fragment处于活跃状态的时候,才能收到LiveData数据更新的通知,这可以确保,数据发生更新的时候,UI的状态也是可以更新的。③可以根据观察者的生命周期变化,在观察者销毁后进行自我清理,避免内存泄露。④当界面重新恢复到活跃状态或者重新创建的时候,会立即接收到最新的数据。
用法
–
见官方文档。
分析:
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:
尾声
开发是需要一定的基础的,我是08年开始进入Android这行的,在这期间经历了Android的鼎盛时期,和所谓的Android”凉了“。中间当然也有着,不可说的心酸,看着身边朋友,同事一个个转前端,换行业,其实当时我的心也有过犹豫,但是我还是坚持下来了,这次的疫情就是一个好的机会,大浪淘沙,优胜劣汰。再等等,说不定下一个黄金浪潮就被你等到了。
- 330页 PDF Android核心笔记
- 几十套阿里 、字节跳动、腾讯、华为、美团等公司2020年的面试题
- PDF和思维脑图,包含知识脉络 + 诸多细节
- Android进阶系统学习视频
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
59591)]
- Android进阶系统学习视频
[外链图片转存中…(img-XdA8tGxP-1714503559591)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!