Jetpack(二):LiveData学习记录

原理

基于Android 10.0

LiveData是一个可观察的数据持有者,是具有组件生命周期感知的,LiveData和RxJava不同,LiveData并不会通知所有的观察者,只会通知处于Active状态的观察者,如果一个观察者处于DESTROYED状态,他将不会收到通知

源码

LiveData.java的observe

private SafeIterableMap, ObserverWrapper> mObservers = new SafeIterableMap<>();

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        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;
        }
        owner.getLifecycle().addObserver(wrapper);
    }

第1个if处,如果观察者当前状态是DESTROYED,就直接返回,此状态不允许注册LiveData

紧接着创建了一个LifecycleBoundObserver包装类,并将owner和observer传入包装类

下面又调用putIfAbsent方法将包装类和observer传入SafeIterableMap。putIfAbsent方法如果传入的key对应的value已经存在,则返回存在的value,不进行替换。如果传入的key对应的value不存在,则添加key和value,返回null

如果existing为null,就会将wrapper添加到Lifecycle中完成注册,这样当我们调用LiveData的observe方法时,实际上是LiveData内部完成了Lifecycle观察者的注册,这样LiveData就具有了观察组件生命周期的能力


LiveData.java的LifecycleBoundObserver

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer observer) {
            super(observer);
            mOwner = owner;
        }

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

        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            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);
        }
    }

这是一个内部类,继承了ObserverWrapper,其中shouldBeActive方法用于判断当前传入的组件的状态是否是Active状态。Active状态包括STARTED和RESUMED状态

同时这个内部类也实现了GenericLifecycleObserver接口,当组件状态发生变化时,会调用onStateChanged方法。这个方法里会判断组件处于DESTROYED状态时,会removeObserver移除观察者,此时,这个观察者不会收到通知

否则,会调用activeStateChanged方法


LiveData.java的activeStateChanged

private abstract class ObserverWrapper {
        final Observer mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;

        ObserverWrapper(Observer observer) {
            mObserver = observer;
        }

        abstract boolean shouldBeActive();

        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }

        void detachObserver() {
        }

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

activeStateChanged方法在抽象类ObserverWrapper中,会根据Active状态和处于Active状态的组件的数量,对onActive方法和onInactive方法进行回调,这两个方法用于扩展LiveData对象。在最后一个if处,如果处于Active状态,则会调用dispatchingValue方法,并将自身传入其中


LiveData.java的dispatchingValue

private 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, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

mDispatchingValue用于标记当前是否处于分发状态,如果处于分发状态,则在第1个if处标记当前分发无效,直接返回

若分发有效,则会进入do-while,不论ObserverWrapper参数initiator是否为null,都会调用considerNotify方法,要么传入当前initiator,要么传入下一个


LiveData.java的considerNotify

private void considerNotify(ObserverWrapper observer) {
        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()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }

方法中进行了多次判断,第1个if处,如果ObserverWrapper的mActive值不为true,就直接return

第2个if处,如果当前observer对应组件的状态不是Active,就会再次调用activeStateChanged方法,传入false,其方法内部会再次判断是否执行onActive方法和onInactive方法的回调

如果判断条件都满足则会调用Observer的onChanged方法,这个方法正是LiveData的observer方法的回调


总结

LiveData的核心原理就是通过observe方法获取并注册观察对象的生命周期,当生命周期状态发生变化时会回调onStateChanged方法判断是否已经把最新的值通知给观察者。如果已经通知就直接返回,如果没有通知,就调用dispatchingValue将最新的值通知给Active状态的观察者进行数据更新

postValue和setValue除了运行的线程不同,最后都会调用dispatchingValue方法


postValue & setValue

调用MutableLiveData的observe方法后,还需要通过这两个方法进行数据更新

源码

LiveData.java的postValue和setValue

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


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


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

我们可以观察到postValue内部加了锁,最后就是将setValue切换到主线程调用

setValue是运行在主线程的,内部调用了dispatchingValue,上面介绍过,也就是其参数ObserverWrapper为null的情况

无论是LiveData的observe方法还是LiveData的postValue和setValue方法,都会调用dispatchingValue方法


Transformations.map

这个方法用于在LiveData对象分发给观察者之前对其中存储的值进行更改

源码

Transformations.java

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

这个方法运行在主线程,先创建一个final的MediatorLiveData,然后调用addSource方法


MediatorLiveData.java的addSource

@MainThread
    public  void addSource(@NonNull LiveData source, @NonNull Observer onChanged) {
        Source 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和onChanged封装到Source类中,调用了plug方法


Source.java的plug

private static class Source implements Observer {
        final LiveData mLiveData;
        final Observer mObserver;
        int mVersion = START_VERSION;

        Source(LiveData liveData, final Observer observer) {
            mLiveData = liveData;
            mObserver = observer;
        }

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

        void unplug() {
            mLiveData.removeObserver(this);
        }

        @Override
        public void onChanged(@Nullable V v) {
            if (mVersion != mLiveData.getVersion()) {
                mVersion = mLiveData.getVersion();
                mObserver.onChanged(v);
            }
        }
    }

可以看到,传入的Observer回调onChanged在这里调用。plug方法里调用了observeForever方法


LiveData.java的observeForever

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

开头调创建AlwaysActive Observer对Observer进行包装,然后调用AlwaysActiveObserver的activeStateChanged方法,内部实际调用的是ObserverWrapper的activeStateChanged方法,上面已经说过,这里不再赘述,看一下这个类是如何实现的


LiveData.java的AlwaysActiveObserver

private class AlwaysActiveObserver extends ObserverWrapper {

        AlwaysActiveObserver(Observer observer) {
            super(observer);
        }

        @Override
        boolean shouldBeActive() {
            return true;
        }
    }

是LiveData的内部类,继承自ObserverWrapper,和ObserverWrapper唯一的区别就是,他永远处于Active状态


应用举例

Transformations.map

在数据发送给观察者之前进行修改

public class TransformActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transform);
        MutableLiveData mutableLiveData = new MutableLiveData<>();
        mutableLiveData.observe(this, new Observer() {
            @Override
            public void onChanged(String s) {
                Log.d("Main", "onChanged1:" + s);
            }
        });

        LiveData transformedLiveData = Transformations.map(mutableLiveData, new Function() {

            @Override
            public Object apply(String input) {
                return input + "+Android进阶揭秘";
            }
        });

        transformedLiveData.observe(this, new Observer() {
            @Override
            public void onChanged(Object o) {
                Log.d("Main", "onChanged2:" + o.toString());
            }
        });

        mutableLiveData.postValue("Android进阶之光");
    }
}

Transformations.switchMap

手动控制监听某一个数据源,并根据需要随时进行切换

public class SwitchActivity extends AppCompatActivity {

    private static final String TAG = "MainAc";
    MutableLiveData mutableLiveData1;
    MutableLiveData mutableLiveData2;
    MutableLiveData liveDataSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_switch);

        mutableLiveData1 = new MutableLiveData<>();
        mutableLiveData2 = new MutableLiveData<>();
        liveDataSwitch = new MutableLiveData<>();

        //switchmap必定返回一个LiveData对象
        LiveData transformedLiveData = Transformations.switchMap(liveDataSwitch, new Function>() {
            @Override
            public LiveData apply(Boolean input) {
                if(input){
                    //切换监听
                    return mutableLiveData1;
                }else{
                    return mutableLiveData2;
                }
            }
        });

        transformedLiveData.observe(this, new Observer() {
            @Override
            public void onChanged(String s) {
                Log.d(TAG, "onChanged:" + s);
            }
        });

        liveDataSwitch.postValue(false);
        mutableLiveData1.postValue("Android进阶之光");
        mutableLiveData2.postValue("Android进阶揭秘");
    }
}

MediatorLiveData

合并多个数据源一起监听

public class MediatorActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mediator);

        MutableLiveData mutableLiveData1 = new MutableLiveData<>();
        MutableLiveData mutableLiveData2 = new MutableLiveData<>();
        MediatorLiveData liveDataMerger = new MediatorLiveData();

        //合并两个数据源
        liveDataMerger.addSource(mutableLiveData1, new Observer() {
            @Override
            public void onChanged(Object o) {
                Log.d("Main", "onChanged1:" + o.toString());
            }
        });

        //合并两个数据源
        liveDataMerger.addSource(mutableLiveData2, new Observer() {
            @Override
            public void onChanged(Object o) {
                Log.d("Main", "onChanged2:" + o.toString());
            }
        });

        liveDataMerger.observe(this, new Observer() {
            @Override
            public void onChanged(Object o) {
                Log.d("Main", "onChanged:" + o.toString());
            }
        });

        //这样任意一个数据源有消息变动都可以观察到
        mutableLiveData1.postValue("Android进阶之光");
    }
}

你可能感兴趣的:(Jetpack(二):LiveData学习记录)