Jetpack(二):LiveData学习记录

原理

基于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进阶之光");
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容