Jetpack之LiveData源码分析

150 阅读2分钟

一、最官方的使用方法,不多BB直接上链接

LIveData使用简介:戳我👉

二、源码分析

1、我们先说一下最简单使用

  • 1、我们一般用LiveData的子类MutableLiveData来定义一个livedata数据
val livedata = MutableLiveData<Boolean>()
  • 2、订阅:有两种方式,一种observer(),一种observerForever()
//第一种
livedata.observe(lifecycleOwner){ boolean ->
    if(boolean){
        // do something
    }
}
//第二种
livedata.observeForever { boolean ->
    if(boolean){
        // do something
    }
}

  • 3、发送数据
//主线程中使用
livedata.setValue(true)
//子线程中使用
livedata.postValie(true)

2、源码分析

  • 1、定义livedata就是创建一个livedata对象,没什么说的
  • 2、订阅,我们以observer来说
    • 第一步,创建观察者和传入的被观察者进行订阅,为了区分,我们将这里创建的被观察者叫:ObserverA livedata_01.png
    • 第二步,将创建的ObserverA放入集合mObservers中 livedata_02.png
  • 3、发送数据
    • 第一步:我们看一下postValue(),在子线程中使用,但是最终还是通过主线程的handler将线程切换到主线程,再通过setValue()去发送数据,那我们就来看看setValue()源码

livedata_03.png

livedata_04.png

    • 第二步:获取ObserverA对象,并调用其onChanged()方法

livedata_05.png

    • 第三步:回调最终的onChanged()

livedata_06.png

livedata_07.png

  • 4、至此,源码分析完毕

三、粘性事件问题

  • 1、我们在使用LiveData时,通常定义livedata数据 -> 订阅 -> 发送数据 -> 发送数据 -> 发送数据~ ;但是还有一种场景,我们定义livedata数据 -> 发送数据 -> 订阅 -> 发送数据 -> 发送数据 -> 发送数据~ ;这样的话,我们在订阅的时候就会收的第一次发送的数据,这就是多为的粘性事件。为什么会有这样的事情呢?
    • 正常情况下: 我们创建livedata,然后订阅,在订阅的时候mLastVersion 和 mVersion的初始值都为-1,然后在setValue()时,mVersion++,这样mLastVersion < mVersion, 就可以进行onChanged()方法的回调了
    • 异常情况下: 我们创建完livedata,然后就setValue(),这时候就将 mVersion++,导致在订阅的时候mLastVersion < mVersion,就执行了onChanged()回调,这个mData就是之前setValue()的数据。

四、END~