Jetpack之LiveData分析

1,514 阅读6分钟

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

概述

官方doc

LiveData属于Jetpack的架构组件,目的在于当底层数据发生更改的时候可以通知到上层UI进行更新,配合MVVM架构使用,是非常舒服的。

个人对它的理解分成两部分:

1.LivaData=Live+Data,Live是指它是有生命的,或者说可以感知到生命周期的变化。Data是指它的本质还是一个数据存储相关的类。

2.实际的实现就是观察者模型,LiveData的观察者(如我们在observe方法的时候传入的匿名observer对象)是与Lifecycle对象(通常是Activity/Fragment)绑定在一起的,在其处于活跃状态(比如对应的Activity处于started,resumed)的时候,LiveData(被观察者)的更新将会通知到观察者(回调到onChanged方法)。

jetpack-livedata-1.png

用它的好处:①最重要的,LiveData作为被观察者可以感知到观察者(Activity/Fragment)的生命周期,自行去管理自身的生命周期。②如上说的,只有当Activity或者Fragment处于活跃状态的时候,才能收到LiveData数据更新的通知,这可以确保,数据发生更新的时候,UI的状态也是可以更新的。③可以根据观察者的生命周期变化,在观察者销毁后进行自我清理,避免内存泄露。④当界面重新恢复到活跃状态或者重新创建的时候,会立即接收到最新的数据。

用法

见官方文档。

分析:

LiveData本身是一个抽象类,在Jetpack组件中唯一的子类是MutableLiveData。公开了两个方法setValue和postValue。两个方法用来更新LiveData的值,前者只能在主线程中调用,后者可以在子线程中调用,通过Handler消息机制,通知到主线程更新。

在这分析这两个方法之前,先来看下,观察者如何订阅LiveData,即LiveData的observe方法:

// 第一个参数是Lifecycle的持有者,比如Activity、Fragment
// 第二个参数是观察者对象,我们一般就是直接创建一个匿名对象
public void observe(LifecycleOwner owner, Observer<T> 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"
 + " with different lifecycles" );
    }
    // 如果返回的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(null);
}

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<T>, 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;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        // mPendingData
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    // 将mPostValueRunnable这个任务抛到主线程执行
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

先看下mPostValueRunnable:

private final Runnable mPostValueRunnable = new Runnable() {
    @Override
    public void run() {
        // 在主线程中完成data的更新
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            // 然后恢复mPendingData为未设置状态
            // 其实mPendingData的作用就是辅助确保data的更新是在主线程中进行
            mPendingData = NOT_SET;
        }
        // postValue最终调用的也是setValue
        setValue((T) newValue);
    }
};

上面还有一点ArchTaskExecutor,这是Jetpack架构中比较独立的一个部分,看下一点:

jetpack-livedata-2.png

TaskExecutor是抽象基类,主要定义了分别在子线程池和主线程处理Runnable的能力。

DefaultTaskExecutor是TaskExecutor的默认实现:

public class DefaultTaskExecutor extends TaskExecutor {
    private final Object mLock = new Object();
    // IO线程池是固定数量为2的线程池
    private ExecutorService mDiskIO = Executors.newFixedThreadPool(2);
    @Nullable
    private volatile Handler mMainHandler;
    @Override
    public void executeOnDiskIO(Runnable runnable) {
        mDiskIO.execute(runnable);
    }
    @Override
    public void postToMainThread(Runnable runnable) {
        // runnable通过关联主线程的Handler,post回主线程执行
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = new Handler(Looper.getMainLooper());
                }
            }
        }
        mMainHandler.post(runnable);
    }
    @Override
    public boolean isMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }
}

ArchTaskExecutor也是TaskExecutor的实现,与DefaultTaskExecutor的不同在于,ArchTaskExecutor的所有对任务的处理都是通过mDelegate这个TaskExecutor的代理对象来完成的,通过ArchTaskExecutor的set方法,客户端可以通过继承TaskExecutor的方式,实现自己的Runnable任务处理逻辑。

@NonNull
private TaskExecutor mDelegate;// 默认实现就是mDefaultTaskExecutor
@NonNull
private TaskExecutor mDefaultTaskExecutor;// DefaultTaskExecutor实例