| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Jetpack之LiveData分析,Android-MVP模式详解 -> 正文阅读 |
|
[移动开发]Jetpack之LiveData分析,Android-MVP模式详解 |
见官方文档。 分析: 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”
} // 如果返回的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 } 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; hanged方法,传入新的data //也就是我们在订阅LiveData的时候,传入的匿名对象重写的onChanged方法 // 到这里,观察者就收到了LiveData的数据变动的通知。 observer.mObserver.onChanged((T) mData); } postValue: postValue用于在子线程通知主线程livedata发生了变化,代码如下: protected void postValue(T value) { boolean postTask; |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 23:45:02- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |