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是一个包装类,是对LifeCycleOwnerLifeCycleObserver的组合。

所以我们总结一下:

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);}

总结整个更新值通知的流程就是:

  1. 切换线程更新值
  2. 根据ObserverWrapper开发逐个监听者分发
  3. 分发的时候要剔除不是激活态的和老版本的不分发

更多相关文章

  1. Android基础学习之AppWidget(桌面小部件)
  2. android学习---SeekBar和RatingBar
  3. Android中Activity生命周期的学习
  4. Android(安卓)Activity及其生命周期
  5. 玩转Android之Activity详细剖析
  6. android 同步监听输入框,以及电话号码正则表达式!
  7. Android之appWidget按钮事件
  8. android实现耳机插入和拔出状态检测
  9. Android(安卓)handler使用方法

随机推荐

  1. 华为交换机口令恢复和重置密码
  2. 一分钟了解交换机-路由器-集线器-防火墙
  3. 京东四面:说说Tomcat 在 SpringBoot 中是
  4. “网关”的特点及存在的价值和意义
  5. 计算机端口号的分类和测试方法
  6. 华为防火墙双机热备(VRRP)的配置实例
  7. 华为ENSP模拟器的使用-在web界面登陆防火
  8. Win10系统怎么添加LOOPBACK环回接口呀?
  9. 华为交换机配置基于IP地址划分VLAN
  10. 华为配置基于MAC地址划分VLAN