Android Jetpack 组件之 LiveData 详解

LiveData 是一个可观察的数据持有者类,与常规 Observable 不同,LiveData 是生命周期感知的,LiveData 也是 Android Jetpack 组件的一部分。

简介

LiveData 是一个可观察的数据持有者类,与常规的 Observable 不同,LiveData 可感知 ActivityFragmentService 的生命周期,确保 LiveData 仅更新处于活动生命周期状态的组件观察者。

如果应用程序组件观察者所处的状态是 STARTEDRESUMED,则 LiveData 认为该组件处于活跃状态,该组件会收到 LiveData 的数据更新,而其他注册的组件观察者将不会收到任何数据更新。如果组件观察者所处的状态改变为 DESTROYED 时,则移除该观察者。

LiveData 的创建基本会在 ViewModel 中,从而使数据在界面销毁时继续保持。

优点

LiveData 具有以下优点:

  • 保持 UI 与数据的一致性:LiveData 遵循观察者设计模式,生命周期发生变化时,LiveData 会通知对应的应用程序组件(Observer),数据发生变化时也会通知更新 UI。
  • 避免内存泄漏:这个 Observer 绑定了 Lifecycle 对象,当 Lifecycle 对象生命周期 destory 之后,这些 Observer 也会被自动清理。
  • 避免 Activity 处于不活跃状态的时候产生崩溃:如果观察者(Observer)处于不活跃状态,则 Observer 不会接收任何 LiveData 事件。
  • 不在手动处理生命周期:UI 组件只是观察相关数据,而不会停止或恢复观察,LiveData 会根据具体生命周期的变化而自动管理。
  • 始终保持最新数据:如果生命周期为非活跃状态,则会在由非活跃状态转为活跃状态时接收最新数据,如从后台切换到前台自动接收最新数据。
  • 正确处理配置更改:如果 Activity 或 Fragment 因为设备配置发生变化而重新创建,比如屏幕旋转等,也将会立即重新接收最新数据。
  • 共享服务:可以借助 LiveData 数据的观察能力,根据 Livecycle 的生命周期状态随时连接或断开服务。

使用

在某个具体的 ViewModel 类中定义 LiveData 数据,然后在对应的 ActivityFragment 中观察 LiveData 数据的变化,LiveData 的使用使得我们不在将数据保存在 ActivityFragment 中,而是将 LiveData 对象中存储的数据保存在 ViewModel 中,减轻了 ActivityFragment 的工作量,使得 ActivityFragment 只负责界面管理和显示,而不在保存数据,且在配置更改时数据不受影响。

LiveData 的使用步骤如下:

  • 在 ViewModel 创建具体的 LiveData 实例来存储数据;
  • 用 LiveData 对象的 observe() 方法将对应的 Activity 或 Fragment 等添加为该 LiveData 对象的观察者;
  • 使用 LiveData 的 setValue() 或 postValue() 方法更新数据,然后在观察者(Activity/Fragment)中获取更新数据。

如果需要创建没有 LifecycleOwner 的观察者,可以使用 LiveData 对象的 observeForever() 方法来将一个没有 LifecycleOwner 的类添加到观察者列表中。不过需要注意的是,使用 observeForever() 方法添加的观察者对象会一直处于活跃状态,此时就需要手动调用 removeObserver() 方法移除该观察者。

转换

LiveData 提供了工具类 Transformations 来对 LiveData 的数据类型进行转换,可以在 LiveData 的数据返回给观察者之前修改 LiveData 中数据的具体类型,比如 int 型数字 1、2 等转化为中文大写壹、贰等,那么如何使用呢,创建 MapViewModel 如下:

map()

LiveData<Y> map(LiveData<X> source, Function<X, Y> mapFunction) 提供一个方法去在 LiveData.setValue() 之前对 value 进行相应的转换和处理。代码示例如下:

private LiveData<User> userLiveData = ...;
private LiveData<String> userFullNameLiveData = Transformations.map(userLiveData, new Function<User, String>() {
    @Override
    public String apply(User user) {
        return user.firstName + user.lastName;
    }
});

switchMap()

LiveData switchMap(LiveData source, Function<X, LiveData> switchMapFunction):与 map()类似,但是是对 LiveData 进行转换,而不是对应的 value。代码示例如下:

class UserViewModel extends AndroidViewModel {

    MutableLiveData<String> nameQueryLiveData = new MutableLiveData<>();

    LiveData<List<String>> getUsersWithNameLiveData() {
        return Transformations.switchMap(nameQueryLiveData, new Function<String, LiveData<List<String>>>() {
            @Override
            public LiveData<List<String>> apply(String name) {
                return mDataSource.getUsersWithNameLiveData(name);
            }
        });
    }

    void setNameQuery(String name) {
        this.nameQueryLiveData.setValue(name);
    }

}

源码解析

Transformations 的源码如下:

public class Transformations {

    @MainThread
    @NonNull
    public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction) {
        // 创建一个MediatorLiveData对象
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
                // 在setValue()前执行了mapFunction并且将新的值赋值给LiveData
                result.setValue(mapFunction.apply(x));
            }
        });
        return result;
    }

    @MainThread
    @NonNull
    public static <X, Y> LiveData<Y> switchMap(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, LiveData<Y>> switchMapFunction) {
        // 创建一个MediatorLiveData对象
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            LiveData<Y> mSource;

            @Override
            public void onChanged(@Nullable X x) {
                // 得到转换后的LiveData
                LiveData<Y> newLiveData = switchMapFunction.apply(x);
                // 如果新获得的LiveData没有发生变化,则直接返回
                if (mSource == newLiveData) {
                    return;
                }
                // 停止监听源LiveData
                if (mSource != null) {
                    result.removeSource(mSource);
                }
                // 将新得到的LiveData赋值给源LiveData
                mSource = newLiveData;
                // 重新重新绑定观察者
                if (mSource != null) {
                    result.addSource(mSource, new Observer<Y>() {
                        @Override
                        public void onChanged(@Nullable Y y) {
                            result.setValue(y);
                        }
                    });
                }
            }
        });
        return result;
    }

}

map() 方法和 switchMap() 方法内部都是由 MediatorLiveData 参与转换。MediatorLiveDataLiveData 的子类,它可以用来正确的处理其他多个 LiveData 的事件变化并处理这些事件。MediatorLiveData 会将自身的 active/inactive 状态变化正确的传递给它所处理的 LiveData。可以自己使用 MediatorLiveData 来实现更多类似 map()switchMap() 这样的数据类型转换。

扩展

LocationLiveData 是一个继承 LiveData 的自定义 LiveData

public class LocationLiveData extends LiveData<Location> {
    private LocationManager locationManager;

    private SimpleLocationListener listener = new SimpleLocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            setValue(location);
        }
    };

    public LocationLiveData(Context context) {
        locationManager = (LocationManager) context.getSystemService(
                Context.LOCATION_SERVICE);
    }

    @Override
    protected void onActive() {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
    }

    @Override
    protected void onInactive() {
        locationManager.removeUpdates(listener);
    }
}

上面有三个值得注意的地方:

  • onActive():当该方法被调用时,表示 LiveData 的观察者数量从0变为了1,这时就应该注册位置监听了。
  • onInactive():当该方法被调用时,表示 LiveData 的观察者数量变为了0,既然没有了观察者,也就没有理由再做监听,此时就应该将位置监听移除。
  • setValue():通过调用该方法来更新 LiveData 的数据,并通知处于活动状态的观察者。

源码分析

LiveData

LiveData 的源码如下:

public abstract class LiveData<T> {

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

    /**
     * 创建一个使用给定值初始化的LiveData
     */
    public LiveData(T value) {
        mData = value;
        mVersion = START_VERSION + 1;
    }

    /**
     * 创建一个未分配任何值的LiveData
     */
    public LiveData() {
        mData = NOT_SET;
        mVersion = START_VERSION;
    }

    @SuppressWarnings("unchecked")
    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;
        // 调用mObserver的onChange()方法,通知观察者数据改变
        observer.mObserver.onChanged((T) mData);
    }

    @SuppressWarnings("WeakerAccess") /* synthetic access */
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                // 调用considerNotify()方法更新数据
                considerNotify(initiator);
                initiator = null;
            } else {
                // 遍历mObservers中所有的Observer,调用considerNotify()方法更新数据
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                     mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

    /**
     * 将给定的观察者添加到给定所有者的生命周期内的观察者列表中
     */
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        // 判断了当前Lifecycler的状态,当状态为DESTROYED时即观察者不处于活跃状态,不用接收数据
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        // 创建LifecycleBoundObserver实例保存传入的LifecycleOwner和Observer,并保存在mObservers
        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;
        }
        // 添加一个LifecycleObserver,当LifecycleOwner更改状态时,将通知该观察者
        owner.getLifecycle().addObserver(wrapper);
    }

    /**
     * 将给定的没有LifecycleOwner的观察者添加到观察者列表中
     */
    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing instanceof LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        wrapper.activeStateChanged(true);
    }

    /**
     * 从观察者列表中删除给定的观察者
     */
    @MainThread
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        assertMainThread("removeObserver");
        ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {
            return;
        }
        // 分离观察者
        removed.detachObserver();
        // 处理观察者的活动状态改变
        removed.activeStateChanged(false);
    }

    /**
     * 删除与给定的{@link LifecycleOwner}关联的所有观察者
     */
    @SuppressWarnings("WeakerAccess")
    @MainThread
    public void removeObservers(@NonNull final LifecycleOwner owner) {
        assertMainThread("removeObservers");
        for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
            if (entry.getValue().isAttachedTo(owner)) {
                removeObserver(entry.getKey());
            }
        }
    }

    /**
     * 设置值(用于在非主线程中更新数据)
     */
    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        // 通过ArchTaskExecutor将操作切换到主线程,mPostValueRunnable内部最终调用的setValue()方法
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

    /**
     * 设置值(如果有活动的观察者,那么值将分发给它们)
     * <p>
     * 该方法必须从主线程调用。如果需要通过后台线程设置值,则可以使用postValue()分发
     */
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

    /**
     * 返回当前值
     * <p>
     * 在后台线程上调用此方法并不能保证将接收到最新的值集
     */
    @SuppressWarnings("unchecked")
    @Nullable
    public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            return (T) data;
        }
        return null;
    }

    int getVersion() {
        return mVersion;
    }

    /**
     * 当活动观察者的数量从0变为1时调用
     */
    protected void onActive() {

    }

    /**
     * 当活动观察者的数量从1变为0时调用
     */
    protected void onInactive() {

    }

    /**
     * 判断LiveData是否具有观察者
     */
    @SuppressWarnings("WeakerAccess")
    public boolean hasObservers() {
        return mObservers.size() > 0;
    }

    /**
     * 判断LiveData是否具有活动的观察者
     */
    @SuppressWarnings("WeakerAccess")
    public boolean hasActiveObservers() {
        return mActiveCount > 0;
    }

    /**
     * LifecycleBoundObserver主要利用Lifecycler的生命周期观察者GenericLifecycleObserver,
     * 前面设置了owner.getLifecycle().addObserver(wrapper)后,当生命周期改变时会回调onStateChange()方法,在生命周期为DESTROYED时移除Observer
     */
    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;    // 保存LifecycleOwner

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);// 调用父类ObserverWrapper的构造函数传递Owner
            mOwner = owner;
        }

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

        /**
         * 实现LifecycleEventObserver当生命周期改变时回调onStateChanged
         */
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
            // 当生命周期改变时会回调onStateChange()方法,在生命周期为DESTROYED时移除Observer
            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在Owner活跃状态改变时回调onActive()和onInactive()方法
     */
    private abstract class ObserverWrapper {
        final Observer<? super T> mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;

        ObserverWrapper(Observer<? super T> observer) {
            mObserver = observer;// 保存观察者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) {
                // 当Owner为活跃状态时回调onActive()
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
                // 当Owner未活跃状态时回调onInactive()
                onInactive();
            }
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }

    /**
     * 一直活跃的观察者
     */
    private class AlwaysActiveObserver extends ObserverWrapper {

        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }

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

    static void assertMainThread(String methodName) {
        if (!ArchTaskExecutor.getInstance().isMainThread()) {
            throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
                    + " thread");
        }
    }
}

MutableLiveData

MutableLiveDataLiveData 的一个子类,它的源码如下:

public class MutableLiveData<T> extends LiveData<T> {

    public MutableLiveData(T value) {
        super(value);
    }

    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }

}

MutableLiveData 重写了 LiveData 中的 postValue()setValue() 方法,内部也只是调用了 super.postValue()super.setValue(),也就是说所有的方法都是在 LiveData 中实现。

参考

LiveData Overview


评论
 上一篇
Android Jetpack 组件之 ViewModel 详解 Android Jetpack 组件之 ViewModel 详解
Android 框架可以管理 UI 控制器(Activity 和 Fragment)的生命周期。Android 框架可能会决定销毁或重新创建 UI 控制器,以响应完全不受控制的某些用户操作或设备事件。 如果系统销毁或重新创建 UI 控制器,
2019-11-27
下一篇 
Android Jetpack 组件之 Lifecycle 详解 Android Jetpack 组件之 Lifecycle 详解
Lifecycle 组件是 Android Jetpack 的一部分,该组件可以感知 Activity 和 Fragment 的生命周期状态的改变,有利于生成更易组织、更轻量化、更易于维护的代码,常用的开发方式就是在组件的对应的生命周期方法
2019-11-07
  目录