Jetpack中LiveData原理分析

202 阅读9分钟

前言

LiveData是一个可观察的数据持有者类,与常规observable不同,LiveData是生命周期感知的,这意味着它尊重其他应用程序组件的生命周期,例如ActivityFragmentService。此感知确保LiveData仅更新处于活动生命周期状态的应用程序组件观察者,它遵循观察者模式,而且不存在内存泄漏问题,观察组件不在活跃状态,不会收到消息,更新UI。

本文侧重原理探究

目录

一、LiveData简单示例

LiveData的使用大家都会,对其优缺点可以参考 Jetpack之LiveData

1、跨组件更新数据

主要是简单的跳转,第二个页面显示数据

public class DataShareActivity extends AppCompatActivity {
    private TextView mTvShare1;
    private Button mBtnShare1;
​
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_data_share);
        findViews();
        mTvShare1.setText("First Page Initialed");
        mBtnShare1.setOnClickListener(v -> {
            ShareLiveData.getInstance().setValue(new ShareModel("First Page Jump To Me"));
            startActivity(new Intent(DataShareActivity.this,DataShareTwoActivity.class));
        });
​
        LiveData<ShareModel> shareModelLiveData = ShareLiveData.getInstance();
        shareModelLiveData.observe(this,(value)->{
            if(value == null){
                return;
            }
            mTvShare1.setText(value.data);
        });

    }
​
    private void findViews() {
​
        mTvShare1 = findViewById(R.id.tv_share_1);
        mBtnShare1 = findViewById(R.id.btn_share_1);
​
    }
}
​

public class DataShareTwoActivity extends AppCompatActivity {
    private TextView mTvShare2;
    private Button mBtnShare2;
​
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_share_two);
        findViews();
​
        mBtnShare2.setOnClickListener(v -> {
            ShareLiveData.getInstance().setValue(new ShareModel("Second Page Back To Me"));
            onBackPressed();
        });
​
        ShareLiveData.getInstance().observe(this, (value) -> {
            if(value == null){
                return;
            }
            mTvShare2.setText(value.data);
        });
    }
​
    private void findViews() {
​
        mTvShare2 = findViewById(R.id.tv_share_2);
        mBtnShare2 = findViewById(R.id.btn_share_2);
​
    }
}

2、更改数据

Transformations.map()

        //Transformations.map()  在LiveData对象分发给观察者之前对其中存储的值进行更改
        LiveData<Object> map = Transformations.map(shareModelLiveData, new Function<ShareModel, Object>() {
            @Override
            public Object apply(ShareModel input) {
                return input.data + " Transformation";
            }
        });
        map.observe(this,(value)->{
            Toast.makeText(DataShareActivity.this, value.toString(), Toast.LENGTH_SHORT).show();
        });

3、数据监听

Transformations.switchMap()

        //监听其中一个的数据变化,并能根据需要随时切换监听
        switchData = new MutableLiveData<>();
        LiveData<ShareModel> transformations = Transformations.switchMap(switchData, new Function<Boolean, LiveData<ShareModel>>() {
            @Override
            public LiveData<ShareModel> apply(Boolean input) {
                if(input){
                    return shareModelLiveData;
                }
                return noShareModelLiveData;
            }
        });
        noShareModelLiveData.observe(this,(value)->{
            Toast.makeText(this, "No Share", Toast.LENGTH_SHORT).show();
        });
        transformations.observe(this,(value)->{
            mTvShare1.append("\nSwitchMap -> "+value.data);
        });
        switchData.setValue(false);
​
        noShareModelLiveData.setValue(new ShareModel("转换NoShare"));
        shareModelLiveData.setValue(new ShareModel("转换Share"));

二、LiveData原理分析

1、observe  

首先看一下相关时序图

shareModelLiveData.observe(this,observer)

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        // 注释 1 
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        // 注释 2 
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        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;
        }
        // 注释 3
        owner.getLifecycle().addObserver(wrapper);
    }

通过传递来的this,获取到 LifecycleRegistry , 获取到当前的状态,如果是DESTROYED,则不处理,在Activity组件走onDestroy时,组件状态将变成DESTROYED,具体Lifecycle 介绍可见

Jetpack中Lifecycle原理分析

将 Observer 封装在 LifecycleBoundObserver 中,并放入 mObservers 中,最后再将封装后的wrapper对象放入Lifecycle,然后该组件就具备了观察生命周期的能力。

Lifecycle观察生命周期变化原理可见xxxx,在生命周期变化时,会回调Observer中的onStateChanged方法和标记了生命周期注解对应的方法,我们可以看下onStateChanged方法,如果有这个方法,生命周期变化时都会调用。

这里注意一下,在Acitivity的onCreate中执行完 LiveData.observe 后,会将观察者包装一下,然后添加到观察者集合中,注入ReportFrament,执行onActivityCreate方法,然后开始分发Lifecycle.Event.ON_CREATE事件,然后ON_START、ON_RESUME事件,界面显示完毕。

LifecycleObserver 子类 LifecycleBoundObserver

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
    @NonNull final LifecycleOwner mOwner;
​
    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
        super(observer);
        mOwner = owner;
    }
​
     @Override
     boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }
​
    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        // 注释 1 
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        // 注释 2 
        activeStateChanged(shouldBeActive());
    }
​
    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner;
    }
​
    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

注释 1 处 ,当组件状态为DESTROYED时,会把该Observer组件移除,所以观察者处于DESTROYED时,不会收到消息通知。否则如注释 2 处,将调用父类ObserverWrapper的 activeStateChanged 方法,其参数 shouldBeActive() ,主要是判断当前State状态是否是STARTED、RESUMED

@Override
boolean shouldBeActive() {
       return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

activeStateChanged()

void activeStateChanged(boolean newActive) {
    if (newActive == mActive) {
       return;
    }
    // immediately set active state, so we'd never dispatch anything to inactive
    // owner
    mActive = newActive;
    // 注释 1
    boolean wasInactive = LiveData.this.mActiveCount == 0;
    LiveData.this.mActiveCount += mActive ? 1 : -1;
    if (wasInactive && mActive) {
        onActive();
    }
    if (LiveData.this.mActiveCount == 0 && !mActive) {
        onInactive();
    }
    // 注释 2
    if (mActive) {
        dispatchingValue(this);
    }
}

该方法主要根据Active状态和处于Active状态的组件的数量,来调用相关方法,状态不变则不处理。

通过对shouldBeActive分析,可以知道只有在STARTED、RESUMED状态时newActive 为true,其它为false,我们这里分析由false 到true的情况,即 newActive 为false、true。

如果newActive 为false ,由于mActive变量初始化是false,所以后面语句不执行,执行不到注释 1 处。

当newActive 从 false 到 true 时,刚开始的时候 mActiveCount是为 0 的,wasInactive为true ,mActiveCount 则从 0 变为 1,onActive方法执行,再执行dispatchingValue(this) 。然后newActive再由 true 到 false 时,wasInactive为false,mActiveCount从 1 到 0,只执行 onInactive 方法。

dispatchingValue(this)

void dispatchingValue(@Nullable ObserverWrapper initiator) {
        //注释 1
        //是否正在向观察者分发中 true 是
        if (mDispatchingValue) {
            //此次分发无效
            mDispatchInvalidated = true;
            return;
        }
        //正在分发
        mDispatchingValue = true;
        do {
            //分发成功 分发有效
            mDispatchInvalidated = false;
            if (initiator != null) {
                //注释 2
                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;
    } 

注释 2 处considerNotify 是真正通知观察者们,调用其onChanged方法 (代码分析直接写在代码中)

    private void considerNotify(ObserverWrapper observer) {
         //注释 1 重新判断组件 状态,也许他们改变了状态,非激活状态 啥也不干
        if (!observer.mActive) {
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        if (!observer.shouldBeActive()) {   // 注释 2 重盘判断,也许状态改变了
            observer.activeStateChanged(false);
            return;
        }
        // 注释 3 mVersion为LiveData的成员变量,每次更新值,例如调用setValue时,会自增,这里判断主要是
        //为了 当观察者进入了活动状态,但是我们并没有收到该事件,即setValue、postValue方法调用,最好不要回掉观察者的onChange方法
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked  注释 4 回掉观察者的 onChange 方法
        observer.mObserver.onChanged((T) mData);
    }

2、setValue  

由于LiveData是个抽象类,我们分析它的子类MutableLiveData

public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }
​
    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

可以看到子类并没有做什么特别的操作,所以setValue还是LiveData进行处理的

    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

注解 @MainThread 说明 setValue 必须在主线程调用, 其中 mVersion ++ 是用于版本比较,上一小节已经分析过,就是为了观察组件进入到活动状态,但是没有收到消息通知时,onChange方法回调。

dispatchingValue方法,之前分析过,唯一的区别就是这里参数是null,我们继续看一下

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    ......
            if (initiator != null) {
                //注释 2
                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;
                    }
........
    } 

可以看到,如果传null的话,它会通知所有观察组件新消息,进行必要的onChange回调,观察组件是从哪里来的呢?之前一节对 observe() 方法分析时,知道mObservers会将所添加的观察者进行包装保存。

3、postValue 

postValue同样是交给了LiveData类处理

    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

与 setValue 不同的是,此方法可以在子线程调用,然后通过 ArchTaskExecutor 切换到主线程,执行 mPostValueRunnable

ArchTaskExecutor是怎么切换到主线程的呢?我们继续追踪ArchTaskExecutor类

    @NonNull
    public static ArchTaskExecutor getInstance() {
        if (sInstance != null) {
            return sInstance;
        }
        synchronized (ArchTaskExecutor.class) {
            if (sInstance == null) {
                sInstance = new ArchTaskExecutor();
            }
        }
        return sInstance;
    }
    private ArchTaskExecutor() {
        mDefaultTaskExecutor = new DefaultTaskExecutor();
        mDelegate = mDefaultTaskExecutor;
    }
    @Override
    public void postToMainThread(Runnable runnable) {
        mDelegate.postToMainThread(runnable);
    }
​

从中可以看出 切换到主线程的功劳还是 DefaultTaskExecutor ,我们直接看它的postToMainThread方法,

    @Override
    public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = new Handler(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }

可以清楚得看到是拿到主线程的Looper,利用Handler向主线程发送消息。

那切换到主线程后,是如何设置数据的呢?我们可以看一下发送的 mPostValueRunnable 消息

    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };

最终还是调用了setValue方法,也就是postValue 通过Handler切换到了主线程,然后调用setValue方法。

2、Transformations.map

    @MainThread  //主线程
    public static <X, Y> LiveData<Y> map(@NonNull LiveData<X> source,
            @NonNull final Function<X, Y> func) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
                result.setValue(func.apply(x));
            }
        });
        return result;
    }

MediatorLiveData 是 MutableLiveData 的子类,直接看其addSource方法

    @MainThread
    public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<S> onChanged) {
        Source<S> e = new Source<>(source, onChanged);
        Source<?> existing = mSources.putIfAbsent(source, e);
        if (existing != null && existing.mObserver != onChanged) {
            throw new IllegalArgumentException(
                    "This source was already added with the different observer");
        }
        if (existing != null) {
            return;
        }
        if (hasActiveObservers()) {
            e.plug();
        }
    }

首先会将外部传入的LiveData 对象 和 构建的观察者 提供给Source对象 e。然后放入到 mSources (SafeIterableMap) 中。

之前分析过,LiveData添加了观察者后,会拥有观察生命周期的能力,可以看之前分析的 activeStateChanged() 方法,组件活动状态,则mActiveCount = 1,因此 hasActiveObservers() 为 true,但是在之前的示例中,onCreate 里面 执行 Transformations.map ,这里是false的,不信,可以打个断点试试。

addSource() 方法调用完后,返回 MediatorLiveData ,然后调用 observe 方法 将观察者包装一下,添加到Lifecycle中。

那什么时候触发mSouces里 存放的 Source对象中观察者的onChanged方法呢?即 下面 这个 new Observer 的 onChange方法

 result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
                result.setValue(func.apply(x));
            }
        });

当这个onChange 方法调用后,通过 result.setValue 才能触发 你在 Activity 中 写的观察者,即之前示例代码DataShareActivity onCreate 中的观察者。

   map.observe(this,(value)->{
            Toast.makeText(DataShareActivity.this, value.toString(), Toast.LENGTH_SHORT).show();
        });

回到onChanged调用时机问题,我们跟踪mSources对象,发现MediatorLiveData 复写了父类的onActive和onInactive方法,内部对mSources 进行了遍历并执行了相应的方法。换句话说,是我们在Activity onCreate 中的 Transformations.map 对 mSources 添加了相应的 LiveData 和 Source 对象,然后 会执行 LifecycleBoundObserver 的 onStateChanged 方法(这里开头分析过了),然后会执行相应的onActive 和 onInactive 方法,组件活动状态下看 onActive 方法即可。

onActive()

    @CallSuper
    @Override
    protected void onActive() {
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().plug();
        }
    }

source.getValue().plug()方法

 void plug() {
      mLiveData.observeForever(this);
 }

observeForever()

    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        //注释 1
        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;
        }
        //注释 2
        wrapper.activeStateChanged(true);
    }

其中注释 1 处的AlwaysActiveObserver 和 LifecycleBoundObserver 不一样的地方在于 shouldBeActive 返回值,前者是固定的 true,永远是活动状态。

    private class AlwaysActiveObserver extends ObserverWrapper {
​
        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }
​
        @Override
        boolean shouldBeActive() {
            return true;
        }
    }

注释 2 调用的是ObserverWrapper的activeStateChanged方法,之前已经讲解了,会回调观察者的 onChanged方法。

3、Transformations.switchMap

switchMap和map类似,此处不过多分析,在代码内进行讲解

    @MainThread
    public static <X, Y> LiveData<Y> switchMap(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, LiveData<Y>> switchMapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            LiveData<Y> mSource;
​
            @Override
            public void onChanged(@Nullable X x) {
            // 注释 1 可以看前面的示例,这里 switchMapFunction.apply(x) 得到一个LiveData
                LiveData<Y> newLiveData = switchMapFunction.apply(x);
                if (mSource == newLiveData) {
                    return;
                }
                if (mSource != null) {
                // 注释 2 先移除前一个LiveData 构建的 Source
                    result.removeSource(mSource);
                }
                //注释 3 重新赋值
                mSource = newLiveData;
                if (mSource != null) {
                //注释 4 添加Source
                    result.addSource(mSource, new Observer<Y>() {
                        @Override
                        public void onChanged(@Nullable Y y) {
                            result.setValue(y);
                        }
                    });
                }
            }
        });
        return result;
    }