美文网首页
Jetpack(二):LiveData学习记录

Jetpack(二):LiveData学习记录

作者: 打工崽 | 来源:发表于2021-07-04 16:29 被阅读0次

    原理

    基于Android 10.0

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

    源码

    LiveData.java的observe

    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
    
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> 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<? super T> 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<? super T> mObserver;
            boolean mActive;
            int mLastVersion = START_VERSION;
    
            ObserverWrapper(Observer<? super T> 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<Map.Entry<Observer<? super T>, 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 <X, Y> LiveData<Y> map(
                @NonNull LiveData<X> source,
                @NonNull final Function<X, Y> mapFunction) {
            final MediatorLiveData<Y> result = new MediatorLiveData<>();
            result.addSource(source, new Observer<X>() {
                @Override
                public void onChanged(@Nullable X x) {
                    result.setValue(mapFunction.apply(x));
                }
            });
            return result;
        }
    

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


    MediatorLiveData.java的addSource

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


    Source.java的plug

    private static class Source<V> implements Observer<V> {
            final LiveData<V> mLiveData;
            final Observer<? super V> mObserver;
            int mVersion = START_VERSION;
    
            Source(LiveData<V> liveData, final Observer<? super V> 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<? super T> 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<? super T> 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<String> mutableLiveData = new MutableLiveData<>();
            mutableLiveData.observe(this, new Observer<String>() {
                @Override
                public void onChanged(String s) {
                    Log.d("Main", "onChanged1:" + s);
                }
            });
    
            LiveData transformedLiveData = Transformations.map(mutableLiveData, new Function<String, Object>() {
    
                @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<String> mutableLiveData1;
        MutableLiveData<String> mutableLiveData2;
        MutableLiveData<Boolean> 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<Boolean, LiveData<String>>() {
                @Override
                public LiveData<String> apply(Boolean input) {
                    if(input){
                        //切换监听
                        return mutableLiveData1;
                    }else{
                        return mutableLiveData2;
                    }
                }
            });
    
            transformedLiveData.observe(this, new Observer<String>() {
                @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<String> mutableLiveData1 = new MutableLiveData<>();
            MutableLiveData<String> mutableLiveData2 = new MutableLiveData<>();
            MediatorLiveData liveDataMerger = new MediatorLiveData<String>();
    
            //合并两个数据源
            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学习记录

          本文链接:https://www.haomeiwen.com/subject/nmbmultx.html