jetpack--LiveData源码解析

286 阅读11分钟

一、LiveData

1. LiveData 观察者包装类的两种实现
(1)ObserverWrapper
 //Observer 包装类
  private abstract class ObserverWrapper {
        //实际的观察者
        final Observer<? super T> mObserver;
        //是否活跃
        boolean mActive;
        //数据版本
        int mLastVersion = START_VERSION;

        ObserverWrapper(Observer<? super T> observer) {
            mObserver = observer;
        }

        abstract boolean shouldBeActive();
        //是否和绑定的生命周期持有者相同  LifecycleBoundObserver 覆写
        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }
        //从生命周期持有者中解绑  LifecycleBoundObserver 覆写
        void detachObserver() {
        }
        //活跃状态变更 ,会更新活跃的数量,并触发给这个Observer 单独发送一次数据
        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }
可以看到ObserverWrapper是个抽象类,里边包含了 实际的观察者、活跃状态、当前观察者的数据版本,并封装 状态变更、判断是否和生命周期持有者绑定、从生命周期持有者中解绑等方法;状态变更的同时会触发活跃数量的变化,也会触发一次给当前变为活跃状态的观察者同步数据的操作

既然是个抽象类,那肯定有实现类,实现类有两个 LifecycleBoundObserver 和 AlwaysActiveObserver

(2)LifecycleBoundObserver 和 AlwaysActiveObserver
  //和生命周期持有者 绑定的观察者 ,根据生命周期持有者的状态决定自己是否变为活跃,并处理添加 和移除操作
    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
      //生命周期持有者  
      @NonNull
        final LifecycleOwner mOwner;
       //构造函数
        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }
        //判断是否活跃,生命周期持有者 state 至少是 STATED 也即 STARTED 和 RESUMED两种
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
        //实现了 LifecycleEventObserver 接口,故可以接收 状态变更回调 如果当前状态是 DESTROYED 则移除 Observer
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
          //如果生命周期已是DESTROYED则移除 Observer  
          if (currentState == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
           //处理观察者状态变更
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            //是否在感应同一个组件的生命周期
            return mOwner == owner;
        }

        @Override
        void detachObserver() {
           // 从生命周期持有者中 移除 观察者
            mOwner.getLifecycle().removeObserver(this);
        }
    }
   
    //实现了一个 一直活跃的Observer
    private class AlwaysActiveObserver extends ObserverWrapper {

        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }

        @Override
        boolean shouldBeActive() {
            return true;
        }
    }
  
}
a.LifecycleBoundObserver 实现了LifecycleEventObserver,因此可以用来绑定到LifeCycleOwner ,用来感知生命周期,来实现自己的活跃状态,当收到生命周期变更为DESTROYED 时,则会移除当前observer,用来保证不能存泄露
b.LifecycleBoundObserver 覆写了 isAttachedTo /和 detachObserver,来处理和 生命周期持有者的绑定关系
c.LifecycleBoundObserver 覆写了 shouldBeActive,用生命周期持有者的state 来决定自己是否应该是活跃的
d.AlwaysActiveObserver 就比较简单了,覆写了shouldBeActive,表示自己应该一直是活跃的
2.LiveData 添加Observer的两种方案
  //注册观察者 参数1 生命周期持有者 参数2 观察者 
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //如果当前生命周期持有者已在 DESTROYED 状态 则直接返回
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        // 将 owner 和 Observer包装成 LifecycleBoundObserver,及可以感知 owner 生命周期
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        // 放入 map 返回为空表示 插入成功,返回有值表明 已经存在了 不允许重复插入
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        // 如果已经插入了,且感知的生命周期和当前的不一样及owner 不一致 则抛出异常
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        //如果已经插入了,且已经链接上 则返回 
        if (existing != null) {
            return;
        }
        //插入成功后 和生命周期持有者链接上,同时感应生命周期变化
        owner.getLifecycle().addObserver(wrapper);
    }
    //添加一个一直活跃的 observer
    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        //如果已经存在,且是LifecycleBoundObserver 则直接抛出异常,因为AlwaysActiveObserver 是没有 owner 的 肯定不相等 
        if (existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        // 已经存在直接返回
        if (existing != null) {
            return;
        }
        //插入成功 将观察者状态置位活跃
        wrapper.activeStateChanged(true);
    }
a.observe 入参有两个 LifeCycleOwner 和 Observer,内部会将 Observer 和 LifeCycleOwner 封装成LifecycleBoundObserver ,这样就可以感知生命周期,来决定数据分发,这也是LiveData 可以感知生命周期的原理;组件生命周期变更后 Observer 会改变自己的活跃状态,用来决定分发数据时是否分发给该Observer
b.observeForever 入参只有一个 Observer, 内部会将Observer 包装成 AlwaysActiveObserver,虽然AlwaysActiveObserver 覆写了 shouleBeActive 一直返回true,但是如果活跃状态没有置为true,一样无法接收数据,也就是observeForever 最后一行代码的作用
c. 在添加观察者时,如果 该观察者已经添加过且 该观察者是LifecycleBoundObserver 类型,且 该观察者监听的生命周期和之前的不一致,则会抛出异常,即无法使用同一观察者感知不同的生命周期持有者
3. Livadata 删除Observer 的两种方案
//删除一个Observer 从map 中移除,并将观察和 和生命周期持有者断开连接,将状态置位不活跃
    @MainThread
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        assertMainThread("removeObserver");
        ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {
            return;
        }
        removed.detachObserver();
        removed.activeStateChanged(false);
    }
    
    //删除和这个观察者绑定的所有Observer,如果加入了多个
    @MainThread
    public void removeObservers(@NonNull final LifecycleOwner owner) {
        assertMainThread("removeObservers");
        for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
            if (entry.getValue().isAttachedTo(owner)) {
                removeObserver(entry.getKey());
            }
        }
    }
删除Observer 有两种方案
a.removeObserver 从map 中移除,并和生命周期持有者解除绑定,并变更为非活跃状态,触发活跃数量变更
b.removeObservers 传入了 生命周期持有者,然后遍历当前所有观察者,会删除所有与当前生命周期持有者绑定的 观察者
4.LiveData 触发数据变更的两种方案
 // 分发数据 将mPendingData 值赋值给 newValue,将mPendingData 设置为初始值 然后通过setValue 通知Observer 更新数据
    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
    };
    
        //设置一个值,该值将先赋值给mPendingData,然后post 到主线程 ,主线程再调用 setValue,该方法可以由子线程发起
    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

    //设置一个值,会立即将该值同步给处于活跃状态的observer,必须在主线程调用
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }


a. postValue 会将数据保存在 mPendingData 中,然后 通过postToMainThread 变更到主线程,主线程执行mPostValueRunnable 然后调用setValue 方法触发数据分发; 该方法可以用在子线程
b.setValue 用在主线程触发数据更新,先将数据版本号+1,然后触发分发数据给所有观察者(活跃的观察者)
c.postValue 会判断 mPendingData 之前是不是NO_SET,如果不是 则只会变更 mPendingData 数据,并不会触发postToMainThread,也就是数据会导致数据丢失,mPendingData = NOT_SET 有两个时机,一个是初始状态,一个是调用了 postToMainThread,也就是在mPostValueRunnable 执行之前,如果触发了postValue,只会改变mPendingData 值,最后执行mPostValueRunnable 时 同步的是最后一次设置的值,中间的数据会丢失
5. LiveData 的数据分发

调用postValue 和 setValue 后会触发 dispatchingValue(null); 我们来看下 dispatchingValue 的实现

 //给单个 Observer分发数据
    private void considerNotify(ObserverWrapper observer) {
        //如果observer 不活跃 则不分发
        if (!observer.mActive) {
            return;
        }
        //如果Observer 不会变为活跃,则 将Observer 状态改为不活跃
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        //如果Observer 的 版本号比当前数据的版本号大 则不分发
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        //将当前数据版本 同步给观察者  然后分发数据
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }
    //分发数据入参 是观察者  会根据入参是否为空决定是发送给 单个观察者 还是  全部观察者
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        //如果正在分发数据 则分发不合法
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        //分发合法
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            //如果传入观察者不为空,则给传入观察者更新数据
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                // 如果传入观察者为空,则遍历观察者列表,更新数据
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }
a.considerNotify 的逻辑是给单个观察者纷发数据,会判断 观察者是否活跃,观察者是否应该是活跃,观察者数据版本号 和 当前数据版本号,然后同步数据版本号,并触发onChanged
b.dispatchingValue 会根据 传入的Observer 是否为空 决定是分发给单个 Observer 还是多个Observer
c.mDispatchInvalidated 的存在这里也有点巧妙;加入 当前正在分发数据,又触发了 数据变更,由于还在分发,分发过程判断mDispatchInvalidated 为true 有新数据,则跳出分发,执行while 判断mDispatchInvalidated 为true,进入新一轮的分发; 也就是,在跳出内部循环的那一刻,之前的观察者可以收到原始数据和新数据,而之后的观察者 则只会收到新数据,旧数据是收不到的
6. LiveData 活跃的观察者数量变更
   //活跃的观察者数量变更
    @MainThread
    void changeActiveCounter(int change) {
        int previousActiveCount = mActiveCount;
        mActiveCount += change;
        //如果正在变更 则返回
        if (mChangingActiveState) {
            return;
        }
        mChangingActiveState = true;
        try {
            //这里使用循环 是因为上面 正在变更时返回了,但 mActiveCount的值变了 防止有处理不到的情况
            while (previousActiveCount != mActiveCount) {
                boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
                boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
                previousActiveCount = mActiveCount;
                if (needToCallActive) {
                    onActive();
                } else if (needToCallInactive) {
                    onInactive();
                }
            }
        } finally {
            mChangingActiveState = false;
        }
    }
a. 新加入一个永久活跃的观察者/或者是感知生命周期的观察者生命周期变更时/ 移除观察者 会触发该逻辑
b.用循环判断是因为假如 数量正在变更,又来了一个变更 可以处理直到最终数量一致;因为如果频繁触发mActivreCount 会变,正在变更中 mChangingActiveState 为true 时会返回
c. 活跃数量 由 >0 变为0 时 会触发 onInactive,由 0 到 >0 时会触发 onActive
d. 在finally 中执行 保证 mChangingActiveState 一定会只为false
7.LiveData 的其他代码
public abstract class LiveData<T> {
    //用于Sychronized 加锁使用
    final Object mDataLock = new Object();
    //起始版本
    static final int START_VERSION = -1;
    //初始值 
    static final Object NOT_SET = new Object();
    //观察者 和  封装后的观察者映射
    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();
    //处于活跃状态的观察者
    int mActiveCount = 0;
    //  观察者是否正在切换活跃状态
    private boolean mChangingActiveState;
    //  数据
    private volatile Object mData;
    //下一个要变化的数据 初始值 = NOT_SET 
    volatile Object mPendingData = NOT_SET;
    // 数据版本
    private int mVersion;
    // 是否正在分发 数据
    private boolean mDispatchingValue;
    // 分发是否合法
    private boolean mDispatchInvalidated;
   

    //构造函数 如果有初始值传进来,则赋值,版本初始值为0 
    public LiveData(T value) {
        mData = value;
        mVersion = START_VERSION + 1;
    }

    //构造函数 没有初始值传进来 ,默认值是 NOT_SET,版本号是 -1
    public LiveData() {
        mData = NOT_SET;
        mVersion = START_VERSION;
    }

    //返回当前值 如果是 NOT_SET,返回null
    @Nullable
    public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            return (T) data;
        }
        return null;
    }
    //获取当前版本号
    int getVersion() {
        return mVersion;
    }

    //当活跃的观察者数量由0 变到 1 时 触发
    protected void onActive() {

    }

    //当活跃的观察者数量由1 变到 0 时触发
    protected void onInactive() {

    }

    //是否有绑定的观察者
    @SuppressWarnings("WeakerAccess")
    public boolean hasObservers() {
        return mObservers.size() > 0;
    }

    //是否有绑定的活跃的观察者
    @SuppressWarnings("WeakerAccess")
    public boolean hasActiveObservers() {
        return mActiveCount > 0;
    }
 
    //检查是否是主线程
    static void assertMainThread(String methodName) {
        if (!ArchTaskExecutor.getInstance().isMainThread()) {
            throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
                    + " thread");
        }
    }
}

二、MutableLiveData 和 Observer

public class MutableLiveData<T> extends LiveData<T> {

    /**
     * Creates a MutableLiveData initialized with the given {@code value}.
     *
     * @param value initial value
     */
    public MutableLiveData(T value) {
        super(value);
    }

    /**
     * Creates a MutableLiveData with no value assigned to it.
     */
    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}
public interface Observer<T> {
    /**
     * Called when the data is changed.
     * @param t  The new data
     */
    void onChanged(T t);
}
a.LiveData 是抽象类,MutableLiveData 是 LiveData 的实现,并无任何新逻辑,全部调用liveData 的方法
b. Observer 是个接口类,本身并无感知生命周期的能力,是通过OberverWapper 包装后才有了生命周期感知能力

三、小结

1.ObserverWrapper 包装了观察者,是否活跃状态,数据版本号,生命周期管理等操作
2. ObserverWrapper 实现1 AlwaysActiveObserver,通过复写shouldBeActivte 返回true,使自己一直处于活跃状态
3. ObserverWrapper 实现2 LifecycleBoundObserver,LifecycleBoundObserver 通过实现 LifecycleEventObserver接口,由于 传入了LifeCycleOwner ,将LifecycleBoundObserver 加入到LifeCycleOwner 的观察者当中用于感知生命周期变化,根据生命周期变化变更当前活跃状态,同时又用于监听value 变化
4.添加Observer 有两种实现方式:一种是通过observe,传入 LifeCycleOwner 和 Observer,会包装成LifecycleEventObserver;一种是通过observeForever,会将observer 包装成 AlwaysActiveObserver;不能重复添加同一个Observer感应不同的生命周期
5.删除Observer 也有两种实现方式: 一种是removeObserver 传入要删除的observer,会从map 中移除,从lifeCycleOwner 中移除,并将活跃状态置位false;一种是removeObservers 通过传入LifecycleOwner,判断当前的列表中的observer 是否和 LifecycleOwner 绑定,并调用第一种方法移除
6.数据更新也有两种方式: 一种是setValue ,主线程调用,调用后立即通知活跃的观察者数据更新;一种是postValue,可以用在子线程,通过handler post 到主线程,然后调用 setValue,此方法会导致数据丢失.
7.dispatchingValue 有一个入参Observer,用来确定是单独给这个Observer 发送数据还是 给所有Observer 发送数据
单独给单个Observer发送数据:当Observer 由非活跃状态变为活跃状态时 会单独发送数据
setvalue 里调用dispatchingValue传入的是null,是给所有活跃的观察者发送数据
8. 发送数据限制:有活跃的观察者,且观察者的数据版本比当前数据版本小 ,数据默认版本是 -1 或者0,观察者数据默认版本是 -1
9.观察者状态变更 会触发 mActiveCount 变更(changeActiveCounter)
(1).绑定的 生命周期持有者状态变更
(2).添加/删除Observer
10.changeActiveCounter 会触发两个变更,当活跃的观察者 从 0 到 > 0 会触发 onActive, 从 >0 到 0 会触发 onInActive
11.LiveData导致数据丢失的两个情况
(1)postValue 在 上次值未分发前再次调用 postvalue
(2)调用dispachingValue 时分发数据A 上次未分发完成时 再次调用 dispachingValue 分发数据B,会导致一部分观察者收到A和B,一部分观察者只能收到B