内容简介:看源码前先考虑下如果要自己实现基本做法:扩展:
看源码前先考虑下如果要自己实现 LiveData
应该怎么做?
基本做法:
setter Observer
扩展:
- 允许子线程更新数据, 因此
setter
需要考虑同步; - 项目中可能多个地方需要用到目标数据,因此回调监听器可以添加多个;
- 数据变化时常常都需要更新UI,而UI有生命周期,因此
Observer
需要提供Lifecycle
相关逻辑支持,包括:- 定义处于哪些生命周期的
Observer
可以收到数据更新; -
onDestroy()
时自动移除Observer
等;
- 定义处于哪些生命周期的
- 如何定义
数据变化
呢? 最简单直接的做法是每次触发setter
方法时都当作数据发生了变化, 遍历通知所有Observer
即可, 更进一步的判定交给调用方; ......
简单使用
// 定义 livedata object ParaConfig { // 定义一个私有的 `MutableLiveData` private val msgLiveData = MutableLiveData<String>() // 开放给外部获取数据更新时,提供不可变的 `LiveData` 即可; fun getMsgLiveData(): LiveData<String> = msgLiveData fun updateMsg(msg: String, inBgThread: Boolean = false) { if (inBgThread) { msgLiveData.postValue(msg) // 在子线程中更新数据 } else { msgLiveData.value = msg // 在主线程中更新数据 } } } 复制代码
// 添加 `Observer` class LiveDataFrag : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 添加一个跟生命周期相关的 `Observer` ParaConfig.getMsgLiveData().observe(this, Observer<String> { newMsg -> tv_msg.text = newMsg }) // 无视生命周期, 每次数据变化时都会回调,需要自行移除observer ParaConfig.getMsgLiveData().observeForever { Logger.d("observeForever: $it","tag_livedata") } } } 复制代码
看源码我还是习惯从调用入口一步步往下看, 以下也是按照这种顺序来;
实现
添加 Observer
// LiveData.java public abstract class LiveData<T> { private static final Object NOT_SET = new Object(); // 实际数据,类型为 Object 而非 T private volatile Object mData = NOT_SET; // 存储所有的 Observer private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers = new SafeIterableMap<>(); // 添加跟生命周期相关的 observer // 目标数据 @MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) { // 若 LifecycleOwner 已处于已被销毁,则忽略该 observer if (owner.getLifecycle().getCurrentState() == DESTROYED) { return; } // 将 LifecycleOwner 和 Observer 功能进行绑定包装 // 生成支持生命周期感知的 Observer: LifecycleBoundObserver LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); // 避免重复添加相同的observer ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); if (existing != null && !existing.isAttachedTo(owner)) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } // 实现对 LifecycleOwner 生命周期的感知 // 关键还是 LifecycleBoundObserver 类,我们马上进去看一下 owner.getLifecycle().addObserver(wrapper); } // 无视生命周期, 每次数据发生变化时,都会回调通知 Observer // 需要手动在不需要时移除 Observer @MainThread public void observeForever(@NonNull Observer<T> observer) { AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } wrapper.activeStateChanged(true); } } 复制代码
MutableLiveData
只是简单重写了 LiveData
的 setValue(T)
/ postValue(T)
方法, 改为 public
而已;
数据如何传递的: setValue(T)
解析
// LiveData.java @MainThread protected void setValue(T value) { // 只能在UI线程中调用,否则抛出异常,崩溃 assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); } private boolean mDispatchingValue; // 若参数 initiator 非空,则表示只通知特定的 ObserverWrapper, 否则是回调通知所有 ObserverWrapper // 由于只在主线程中调用,因此不用做多线程处理 private void dispatchingValue(@Nullable ObserverWrapper initiator) { // 小技巧: 在遍历通知各 ObserverWrapper 期间, 若数据发生了变化, 则会重新遍历通知 if (mDispatchingValue) { mDispatchInvalidated = true; return; } mDispatchingValue = true; do { mDispatchInvalidated = false; if (initiator != null) {// initiator 非空时,只更新特定 ObserverWrapper considerNotify(initiator); // 实际更新数据的方法 initiator = null; } else { // 否则遍历更新所有 ObserverWrapper for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator = mObservers.iteratorWithAdditions(); iterator.hasNext(); ) { considerNotify(iterator.next().getValue()); // 若数据发生变化, 则退出for循环 // 而外层 do...while() 判定条件为true,就会重新遍历通知各 ObserverWrapper; if (mDispatchInvalidated) { break; } } } } while (mDispatchInvalidated); mDispatchingValue = false; } // 判断是否要将数据分发到指定的 ObserverWrapper private void considerNotify(ObserverWrapper observer) { // 是否可以分发数据到指定的 observer, 由 mActive 来控制 // 所以 mActive 很重要,具体下一节解读 if (!observer.mActive) { return; } // 二次确认状态, 可能生命周期发生了变化,但 mActive 并未改变 if (!observer.shouldBeActive()) { // active -> inactive 时通知更新状态 // inactive 状态下就不需要分发数据了 observer.activeStateChanged(false); return; } // 若 ObserverWrapper 持有的数据值已是最新版本, 自然也不用分发 if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; // 通知 observer 数据有更新 // observer.mObserver 是调用方实际传入的 observer.mObserver.onChanged((T) mData); } 复制代码
用于子线程调用的 postValue(T)
会发射一个 Runnable
到主线程中, 最终也是通过 setValue(T)
来实现数据分发; 当然, postValue(T)
也可以在主线程调用,不过是多此一举,如:
// observer会先收到 "msgFromSetValue" 然后才收到 "msgFromPostValue" someBtnView.setOnClickListener { msgLiveData.postValue("msgFromPostValue") msgLiveData.value = "msgFromSetValue" } 复制代码
ObserverWrapper
类解析
// LiveData 的内部抽象类 // 包装用户传入的 Observer, 提供数据版本记录以及active状态(生命周期)判断 private abstract class ObserverWrapper { final Observer<T> mObserver; boolean mActive; // 确定当前 ObserverWrapper 是否生效,true时才可进行数据更新 int mLastVersion = START_VERSION; // 当前持有的数据版本号,初始值为 -1 ObserverWrapper(Observer<T> observer) { mObserver = observer; } // 判断该 Observer 是否有效, true 时才会触发 activeStateChanged() abstract boolean shouldBeActive(); boolean isAttachedTo(LifecycleOwner owner) { return false; } void detachObserver() { } // 更新本 ObserverWrapper 的状态 void activeStateChanged(boolean newActive) { // 若状态没变化,不需要更新,直接返回 if (newActive == mActive) { return; } mActive = newActive; boolean wasInactive = LiveData.this.mActiveCount == 0; LiveData.this.mActiveCount += mActive ? 1 : -1; // 处于 active 状态的 observer 数量从0 -> 1时,触发 onActive() 方法 if (wasInactive && mActive) { onActive(); } // 处于 active 状态的 observer 数量从 1 -> 0时,触发 onInactive() 方法 // 提供给观察者释放资源的机会 if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); } // observer 从 inactive -> active 时, 更新数据 if (mActive) { // 将数据发送给该 observer dispatchingValue(this); } } } 复制代码
此类并未给出 inactive/active 具体是何种状态, 具体应是由 shouldBeActive()
来确定, 因此需要从子类查找;
子类 AlwaysActiveObserver
比较简单, 只是将 shouldBeActive()
固定返回 true
,表示一直生效, 每次数据发生变化时都需要发送通知; 我们看下 LifecycleBoundObserver
类;
LifecycleBoundObserver
解析
// LiveData 内部类 // 将 LifecycleObserver 和 ObserverWrapper 结合,当生命周期变化时,通知 ObserverWrapper 更新数据 class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { @NonNull final LifecycleOwner mOwner; LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) { super(observer); mOwner = owner; } @Override boolean shouldBeActive() { // 此处定义了哪些生命周期是 `active` 的 // 结合 Lifecycle.State 类 ,我们知道是: STARTED/RESUMED 两种状态 // 对应于生命周期 `onStart()` 之后到 `onStop()` 之前 return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); } // 生命周期变化时回调本方法 @Override public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) { // 若当前 LifecycleOwner onDestory() 了, 则自动移除 observer, 避免内存泄露 if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } // 将 shouldBeActive() 返回的状态当做本 ObserverWrapper 的状态 // 即 mActive = shouldBeActive() activeStateChanged(shouldBeActive()); } @Override boolean isAttachedTo(LifecycleOwner owner) { return mOwner == owner; } @Override void detachObserver() { mOwner.getLifecycle().removeObserver(this); } } 复制代码
以上所述就是小编给大家介绍的《LiveData源码解析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- ReactNative源码解析-初识源码
- Spring源码系列:BeanDefinition源码解析
- Spring源码分析:AOP源码解析(下篇)
- Spring源码分析:AOP源码解析(上篇)
- 注册中心 Eureka 源码解析 —— EndPoint 与 解析器
- 新一代Json解析库Moshi源码解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Advanced Web Metrics with Google Analytics, 2nd Edition
Brian Clifton / Sybex / 2010-3-15 / USD 39.99
Valuable tips and tricks for using the latest version of Google Analytics Packed with insider tips and tricks, this how-to guide is fully revised to cover the latest version of Google Analytics and sh......一起来看看 《Advanced Web Metrics with Google Analytics, 2nd Edition》 这本书的介绍吧!