LiveData源码分析1 -- 概述和简单使用

917 阅读4分钟

前言

前面聊完了Lifecycle后我们继续来看LiveData,LiveData的源码不多,我们来看看。

正文

LiveData作为在ViewModel中的重要角色,其具有生命周期的可观测属性可以让代码在处理内存泄漏时有更好的效果,同时也是数据驱动的关键。

源码注释

还是看代码先看注释,LiveData有效注释如下:

LiveData is a data holder class that can be observed within a given lifecycle.
* This means that an {@link Observer} can be added in a pair with a {@link LifecycleOwner}, and
* this observer will be notified about modifications of the wrapped data only if the paired
* LifecycleOwner is in active state. LifecycleOwner is considered as active, if its state is
* {@link Lifecycle.State#STARTED} or {@link Lifecycle.State#RESUMED}
  • LiveData是一个在给定Lifecycle的情况下可以被观察的数据持有类,首先它是数据持有类,其次可以被观察,然后就必须要有Lifecycle的前提下。

  • 这也就意味着当添加一个观察者时必须要配套有个LifecycleOwner,而且只有这个配套的LifecycleOwner处于活跃期时,被包裹的数据发生了变化,才会通知观察者。

  • Lifecycle在其保存的State是STARTED或者RESUMED时,这个State在前面Lifecycle源码中都十分熟悉了。

  • 也可以通过observerForever方法来添加一直活跃的观察者,也就是不论LifecycleOwner处于什么状态,它都可以通知变化,当然也需要使用removeObserver来移除这种观察者。

An observer added with a Lifecycle will be automatically removed if the corresponding
* Lifecycle moves to {@link Lifecycle.State#DESTROYED} state. This is especially useful for
* activities and fragments where they can safely observe LiveData and not worry about leaks:
* they will be instantly unsubscribed when they are destroyed.
  • 当被添加的观察者对应的Lifecycle状态切换到DESTROYED时,这个观察者会被自动的移除掉。

  • 这个特性特别有用,Activity/Fragment可以安全地观察LiveData,同时也不必担心内存泄漏,因为当Activity/Fragment被destroy时,观察者会立即取消注册。

In addition, LiveData has {@link LiveData#onActive()} and {@link LiveData#onInactive()} methods
* to get notified when number of active {@link Observer}s change between 0 and 1.
* This allows LiveData to release any heavy resources when it does not have any Observers that
* are actively observing.
  • 而且当LiveData的活跃观察者数量在0和1之间变化时会回调其onActive和onInactive方法。

  • 这个机制可以在LiveData没有活跃观察者时可以释放其任何繁重的任务资源。

This class is designed to hold individual data fields of {@link ViewModel},
* but can also be used for sharing data between different modules in your application
* in a decoupled fashion
  • 这个类通常用来保存ViewModel中的字段,当在多模块共享数据时很有用。

上面就是LiveData所有注释,也大概说明了LiveData的作用以及设计思想,大概来说就是LiveData是具有生命周期感知能力的可观察数据持有类。

MutableLiveData

说完LiveData,再说一个我们配合一起常用的类,也就是MutableLiveData,它继承至LiveData,是可变的LiveData,意思也就是它有 set 方法,可以修改其包裹的值。

//MutableLiveData源码
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);
    }
}

可以看出如果你想使用LiveData并且改变其包裹的值,必须使用MutableLiveData才可以。

最常见的用法

在说源码之前,还是说一下在项目中,LiveData是如何使用的,下面代码:

//ViewModel中定义需要观察的数据,即DataQueryType

//LiveData类型,且访问权限是public,无法给这个变量赋值,是用来给别的组件观察所用
val queryDataType: LiveData<DataQueryType>
    get() = _queryDataType
//MutableLiveData类型,访问权限是private,可以给这个变量赋值,在ViewModel中赋值
private val _queryDataType = MutableLiveData(DataQueryType.MINUTE)

其实这里还挺麻烦,假如我们就使用一个MutableLiveData对象时且使用public访问权限,这个对象的值既可以在Activity中被观察,也可以在Activity中被修改,这明显不符合MVVM架构,所以这里设计2个变量,MutableLiveData在ViewModel可以被修改:

//ViewModel中的方法
fun setDataType(position: Int) {
    //修改MutableLiveData中持有的值
    _queryDataType.value = when (position) {
        0 -> DataQueryType.MINUTE
        1 -> DataQueryType.HOUR
        2 -> DataQueryType.DAY
        else -> DataQueryType.MINUTE
    }
}

然后在Activity/Fragment中进行观察:

//ViewModel实例
dataQueryViewModel.apply {
    //观察LiveData
    queryDataType.observe(this@DataQueryFragment){
        //...
    }
 }

上面代码就是在View层进行观察,这也是数据驱动思想的主要实现,通过LiveData把信息从ViewModel层传递到View层。

总结

本篇文章就到这里,主要是翻译其注释和举例最简单的使用,通过注释我们也就大概了解了LiveData的一些特性,下篇文章我们来全面分析一下其源码实现,然后说一些LiveData的扩展使用。