LiveData源码分析
LiveData源码分析
LiveData是Android提供的监听数据更新的框架,它能够感应Activity/Fragment的生命周期,接下来的内容我们来通过简单的用法去探索LiveData源码的核心知识点。
LiveData感应生命周期的核心
Android涉及到生命周期的时候,基本都是和Lifecycle类有关,我们先来看一下
**LiveData.observe(LifecycleOwner owner, @NonNull Observer<? super T> observer)**里面的代码:
@MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { if (owner.getLifecycle().getCurrentState() == DESTROYED) { // ignore return; } LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); ... ... owner.getLifecycle().addObserver(wrapper);}
Lifecycle是谷歌提供的用来监听Activity与Fragment的生命周期变化,Lifecycle提供了两个接口:
- LifeCycleOwner 生命周期的拥有者,也就是Activity/Fragment,其Android源码Activity一般都继承这个接口
- LifeCycleObserver 生命周期的观察者,可以是任何类,常见的有MVP的P
上面简单的讲解了Lifecycle的作用,回到上面那段代码,我们可以看到,当检测到当前是生命周期是DESTROYED的时候,直接忽略掉,不进行添加任何监听器。
接下来我们再看看LifecycleBoundObserver类:
class LifecycleBoundObserver extends ObserverWrapper
LifecycleBoundObserver类是ObserverWrapper抽象类的子类:
private abstract class ObserverWrapper { ....// 是否激活状态 abstract boolean shouldBeActive(); boolean isAttachedTo(LifecycleOwner owner) { return false; }//分离监听 void detachObserver() { }//激活状态改变 void activeStateChanged(boolean newActive) { .... }}
可以看到,ObserverWrapper抽象类主要是定义了一些固定的规范,然后我们看看LifecycleBoundObserver类的代码:
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { @NonNull final LifecycleOwner mOwner; LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) { super(observer); mOwner = owner; } @Override boolean shouldBeActive() {// 只有大于Start状态才是激活状态 return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); } @Override public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {// 当前是DESTROYED状态的时候直接不处理,并删除监听 if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } activeStateChanged(shouldBeActive()); } @Override boolean isAttachedTo(LifecycleOwner owner) { return mOwner == owner; } @Override void detachObserver() {//移除监听 mOwner.getLifecycle().removeObserver(this); }}
LifecycleBoundObserver是一个包装类,是对LifeCycleOwner和LifeCycleObserver的组合。
所以我们总结一下:
LiveData是通过Lifecycle来感应生命周期的,当Activity/Fragment在Start和Destory之间时,才会发送更新信息,否则不进行更新,想要更具体的理解这一块内容,还是得往下看。
LiveData注册监听器
LiveData用监听的处理分两种:
- 能够感应生命周期
- 不考虑感应生命周期
我们先来看看能够感应生命周期的代码段:
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {// 1.0检测当前是否是主线程 assertMainThread("observe");// 2.0当前是DESTROYED状态,直接忽略 if (owner.getLifecycle().getCurrentState() == DESTROYED) { return; }// 3.0把生命周期拥有者和观察者包装起来 LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);// 4.0 以Map的结构添加包装类,然后判断是否已经添加过了,已经添加则抛出异常 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; }// 5.0将监听者添加到相应位置 owner.getLifecycle().addObserver(wrapper);}
总结流程如下:
- 检测当前是否是主线程
- 当前是DESTROYED状态,直接忽略
- 把生命周期拥有者和观察者包装起来
- 以Map的结构添加包装类,然后判断是否已经添加过了,已经添加则抛出异常
- 将监听者添加到相应位置
然后我们再看看不考虑感应生命周期的代码段:
public void observeForever(@NonNull Observer<? super T> observer) { assertMainThread("observeForever"); 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);}
可以看到不考虑感应生命周期的时候,基本流程和感应生命周期的一致,只是使用了不同的ObserverWrapper抽象类的包装子类,我们来看看AlwaysActiveObserver的代码:
private class AlwaysActiveObserver extends ObserverWrapper { AlwaysActiveObserver(Observer<? super T> observer) { super(observer); } @Override boolean shouldBeActive() { return true; }}
从AlwaysActiveObserver类中的激活状态是永远返回True的,那么说明其永远都是激活态。
LiveData发送更新数据信息
LiveData提供了两个方法进行更新数据:
- postValue:非主线程更新数据
- setValue:必须在主线程才能更新数据,否则会抛出异常
我们先看看LiveData.postValue的代码:
protected void postValue(T value) { boolean postTask;1.0 加锁,并把value赋值给全局变量mPendingData synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; }2.0 判断mPendingData是否已经完成之前的任务 if (!postTask) { return; }3.0 切换到主线程执行任务 ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}private final Runnable mPostValueRunnable = new Runnable() { @Override public void run() { Object newValue;4.0 把mPendingData全局变量赋值给局部变量,然后把mPendingData恢复初始状态 synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; }5.0 设置更新值 setValue((T) newValue); }};
从上面的代码,我们可以总结出,LiveData.postValue主要是做了线程的切换工作,最终还是由LiveData.setValue来完成数据的更新提醒:
protected void setValue(T value) { assertMainThread("setValue");//版本+1 mVersion++;// 全局变量保存需要更新的值 mData = value; dispatchingValue(null);}void dispatchingValue(@Nullable ObserverWrapper initiator) { ... do { mDispatchInvalidated = false; if (initiator != null) {// 更新数据的通知 considerNotify(initiator); initiator = null; } else { for (Iterator, ObserverWrapper>> iterator = mObservers.iteratorWithAdditions(); iterator.hasNext(); ) { considerNotify(iterator.next().getValue()); ... } } } while (mDispatchInvalidated); mDispatchingValue = false;}private void considerNotify(ObserverWrapper observer) {// 不是激活状态不处理 if (!observer.mActive) { return; } // 判断是不处于激活状态 if (!observer.shouldBeActive()) {// 通知激活状态改为false observer.activeStateChanged(false); return; }// 监听者的版本号大于当前的版本号不分发 if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; // 通知数据的更新 observer.mObserver.onChanged((T) mData);}
总结整个更新值通知的流程就是:
- 切换线程更新值
- 根据ObserverWrapper开发逐个监听者分发
- 分发的时候要剔除不是激活态的和老版本的不分发
更多相关文章
- Android基础学习之AppWidget(桌面小部件)
- android学习---SeekBar和RatingBar
- Android中Activity生命周期的学习
- Android(安卓)Activity及其生命周期
- 玩转Android之Activity详细剖析
- android 同步监听输入框,以及电话号码正则表达式!
- Android之appWidget按钮事件
- android实现耳机插入和拔出状态检测
- Android(安卓)handler使用方法