LiveData源码分析

LiveData源码分析

LiveData是Android提供的监听数据更新的框架,它能够感应Activity/Fragment的生命周期,接下来的内容我们来通过简单的用法去探索LiveData源码的核心知识点。

LiveData感应生命周期的核心

Android涉及到生命周期的时候,基本都是和Lifecycle类有关,我们先来看一下

**LiveData.observe(LifecycleOwner owner, @NonNull Observer observer)**里面的代码:

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer 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 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 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 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 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. 分发的时候要剔除不是激活态的和老版本的不分发

你可能感兴趣的:(Android源码分析)