Android Jetpack 之 LiveData - 3

这是我参与更文挑战的第22天,活动详情查看: 更文挑战java

源码分析

LiveData#observe

private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

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

复制代码

咱们调用observer()时,传递了两个参数,第一个是LifecycleOwner接口实例,而咱们继承的AppCompatActivity的父类就已经实现了这个接口,因此咱们传this便可;第二个参数Observer就是咱们观察的回调。android

先判断是否是主线程,不是就抛异常,而后经过 owner.getLifecycle().getCurrentState() 获取状态,判断是否已经被销毁,若是已经被销毁,直接返回(由于已经说过只对处于活跃状态的组件作更新);git

接着将owner和observer构形成LifecycleBoundObserver实例,这是一个内部类,里面有关于状态变换的一系列操做,待会详细分析;github

而后将observer和wrapper存入map缓存中,若是observer缓存已存在而且已经和另外一个LifecycleOwner绑定,则抛出异常;若是缓存已经存在则直接忽略;缓存

即一个 Observer 实例,只能绑定一个 LifecycleOwner,而一个 owner 能够绑定多个 Observer 实例;markdown

最后调用addObserver方法将LifecycleBoundObserver实例和LifecycleOwner绑定。而addObserver是调用了LifecycleRegistry类的实现。app

当 owner (Activity 或者 fragment) 生命周期变化的时候,会回调 LifecycleBoundObserver 的 onStateChanged 方法,onStateChanged 方法又会回调 observer 的 onChange 方法。异步

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);
        }
    }
复制代码
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;
            // 激活状态的 observer 个数从 0 到 1
            if (wasInactive && mActive) {
                onActive();// 空实现,通常让子类去重写
            }
            // 激活状态的 observer 个数从 1 到 0
            if (LiveData.this.mActiveCount == 0 && !mActive) {
                onInactive();// 空实现,通常让子类去重写
            }
            // 激活状态,向观察者发送 LiveData 的值
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }
复制代码

咱们来看一下 LifecycleBoundObserver,继承 ObserverWrapper,实现了 GenericLifecycleObserver 接口。而 GenericLifecycleObserver 接口又实现了 LifecycleObserver 接口。它包装了咱们外部的 observer,有点相似于代理模式。咱们能够回顾下Lifecycle组件相关的内容。当组件(Fragment、Activity)生命周期变化时会经过onStateChanged()方法回调过来。ide

GenericLifecycleObserver#onStateChangedoop

Activity 回调周期变化的时候,会回调 onStateChanged ,会先判断 mOwner.getLifecycle().getCurrentState() 是否已经 destroy 了,若是。已经 destroy,直接移除观察者。这也就是为何咱们不须要手动 remove observer 的缘由

若是不是销毁状态,会调用 activeStateChanged 方法 ,携带的参数为 shouldBeActive() 返回的值。 而当 lifecycle 的 state 为 STARTED 或者 RESUMED 的时候,shouldBeActive 方法的返回值为 true,即表示激活。

activeStateChanged 方法中,,当 newActive 为 true,而且不等于上一次的值,会增长 LiveData 的 mActiveCount 计数。接着能够看到,onActive 会在 mActiveCount 为 1 时触发,onInactive 方法则只会在 mActiveCount 为 0 时触发。即回调 onActive 方法的时候活跃的 observer 刚好为 1,回调 onInactive 方法的时候,没有一个 Observer 处于激活状态。

当 mActive 为 true 时,会促发 dispatchingValue 方法。

@SuppressWarnings("WeakerAccess") /* synthetic access */
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        // 若是正在处理,直接返回
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            // initiator 不为 null,调用 considerNotify 方法
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else { // 为 null 的时候,遍历全部的 obsever,进行分发
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
         // 分发完成,设置为 false
        mDispatchingValue = false;
    }
复制代码

其中 mDispatchingValue, mDispatchInvalidated 只在 dispatchingValue 方法中使用,显然这两个变量是为了防止重复分发相同的内容。当 initiator 不为 null,只处理当前 observer,为 null 的时候,遍历全部的 obsever,进行分发

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. 若是状态不是在活跃中,直接返回,这也就是为何当咱们的 Activity 处于 onPause, onStop, onDestroy 的时候,不会回调 observer 的 onChange 方法的缘由。
  2. 判断数据是不是最新,若是是最新,返回,不处理
  3. 数据不是最新,回调 mObserver.onChanged 方法。并将 mData 传递过去

LiveData#setValue

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

setValue 方法中,首先,断言是主线程,接着 mVersion + 1; 并将 value 赋值给 mData,接着调用 dispatchingValue 方法。dispatchingValue 传递 null,表明处理全部 的 observer。

这个时候若是咱们依附的 activity 处于 onPause 或者 onStop 的时候,虽然在 dispatchingValue 方法中直接返回,不会调用 observer 的 onChange 方法。可是当所依附的 activity 从新回到前台的时候,会促发 LifecycleBoundObserver onStateChange 方法,onStateChange 又会调用 dispatchingValue 方法,在该方法中,由于 mLastVersion < mVersion。因此会回调 obsever 的 onChange 方法,这也就是 LiveData 设计得比较巧妙的一个地方

同理,当 activity 处于后台的时候,您屡次调用 livedata 的 setValue 方法,最终只会回调 livedata observer 的 onChange 方法一次。

LiveData#postValue

protected void postValue(T value) {
        boolean postTask;
    	// 锁住
        synchronized (mDataLock) {
             // 当前没有人在处理 post 任务
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                 // 处理完毕以后将 mPendingData 置为 NOT_SET
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };
复制代码
  1. 首先,采用同步机制,经过 postTask = mPendingData == NOT_SET 有没有人在处理任务。 true,没人在处理任务, false ,有人在处理任务,有人在处理任务的话,直接返回
  2. 调用 AppToolkitTaskExecutor.getInstance().postToMainThread 到主线程执行 mPostValueRunnable 任务。

LiveData#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);
    }
复制代码

由于 AlwaysActiveObserver 没有实现 GenericLifecycleObserver 方法接口,因此在 Activity o生命周期变化的时候,不会回调 onStateChange 方法。从而也不会主动 remove 掉 observer。由于咱们的 obsever 被 remove 掉是依赖于 Activity 生命周期变化的时候,回调 GenericLifecycleObserver 的 onStateChange 方法。

时序图

借用网上的一张图

image.png

LiveData主要涉及到的时序有三个:

  • 在Fragment/Activity中经过LiveData.observer()添加观察者(observer()方法中的第二个参数)。
  • 根据Fragment/Activity生命周期发生变化时,移除观察者或者通知观察者更新数据。
  • 当调用LiveData的setValue()、postValue()方法后,通知观察者更新数据。

todo

NetworkBoundResource

juejin.cn/post/684490…

权限

juejin.cn/post/5c106a…

总结

LiveData优势

1. 确保UI符合数据状态 LiveData遵循观察者模式。 当生命周期状态改变时,LiveData会向Observer发出通知。 您能够把更新UI的代码合并在这些Observer对象中。没必要去考虑致使数据变化的各个时机,每次数据有变化,Observer都会去更新UI。

2. 没有内存泄漏 Observer会绑定具备生命周期的对象,并在这个绑定的对象被销毁后自行清理。

3. 不会因中止Activity而发生崩溃 若是Observer的生命周期处于非活跃状态,例如在后退堆栈中的Activity,就不会收到任何LiveData事件的通知。

4.不须要手动处理生命周期 UI组件只须要去观察相关数据,不须要手动去中止或恢复观察。LiveData会进行自动管理这些事情,由于在观察时,它会感知到相应组件的生命周期变化。

5. 始终保持最新的数据 若是一个对象的生命周期变到非活跃状态,它将在再次变为活跃状态时接收最新的数据。 例如,后台Activity在返回到前台后当即收到最新数据。

6. 正确应对配置更改 若是一个Activity或Fragment因为配置更改(如设备旋转)而从新建立,它会当即收到最新的可用数据。

7.共享资源 您可使用单例模式扩展LiveData对象并包装成系统服务,以便在应用程序中进行共享。LiveData对象一旦链接到系统服务,任何须要该资源的Observer都只需观察这个LiveData对象。

使用 LiveData 对象步骤

  • LiveData基于观察者模式实现,而且和LifecycleOwner进行绑定,而LifecycleOwner又被Fragment和Activity实现,因此它能够感知生命周期;在当前的LifecycleOwner不处于活动状态(例如onPasue()onStop())时,LiveData是不会回调observe()的,由于没有意义.
  • 同时LiveData只会在LifecycleOwner处于Active的状态下通知数据改变,果数据改变发生在非 active 状态,数据会变化,可是不发送通知,等 owner 回到 active 的状态下,再发送通知;
  • LiveData在DESTROYED时会移除Observer,取消订阅,不会出现内存泄漏
  • postValue在异步线程,setValue在主线程
  • 若是LiveData没有被observe(),那么此时你调用这个LiveData的postValue(...)/value=...,是没有任何做用

参考

官方文档:LiveData 概览

Jetpack源码解析—LiveData的使用及工做原理

Android livedata 源码解剖

Android源码解析-LiveData

相关文章
相关标签/搜索