我是靠谱客的博主 专一翅膀,这篇文章主要介绍LiveData的使用和原理,现在分享给大家,希望可以做个参考。

一、LiveData的基本使用
复制代码
1
2
3
4
5
6
7
8
9
10
11
//创建一个LiveData对象 private val livedata = MutableLiveData<String>(); //为LiveData设置监听 livedata.observe(this, Observer { Log.e("znh", "监听到livedata的数据了:${it}") }) //设置LiveData的值 livedata.value = "测试数据"

上述代码中,当LiveData的value值改变时,就会触发observe方法中设置的监听。

二、LiveData的工作原理

MutableLiveData的observe方法里需要传递两个参数,第一个参数是LifecycleOwner的子类,实现了这个接口的子类就是一个被观察者,AppCompatActivity实现了LifecycleOwner接口成为了一个生命周期可被观察的被观察者,所以第一个参数可以设置为Activity自身。第二个参数是观察LiveData数据的观察者Observer。

在LiveData的observe方法中,会将LifecycleOwner和Observer两个参数关联起来封装到wrapper中去,然后将wrapper作为Lifecycle的一个观察者添加到观察者集合中,这样当Activity的生命周期发生改变时,wrapper就可以感知到(具体的感知过程可以查看《Lifecycle的基本使用和原理》),这样Livedata就可以根据wrapper感知到的生命周期状态去处理跟Activity的关系,并决定是否要向Observer发送Livedata的数据。

除了上面Activity的生命周期发生改变时,有可能会触发向Observer发送Livedata数据的一个事件外,当LiveData的setValue或者postValue被调用时也会触发这样一个事件(具体的过程是通过调用dispatchingValue方法来实现的)。

下面看下LiveData的observe方法源码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { assertMainThread("observe"); //注释1 判断owner的生命周期状态是不是被销毁了 if (owner.getLifecycle().getCurrentState() == DESTROYED) { // ignore return; } //注释2 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; } //注释3 为lifecycle添加观察者 owner.getLifecycle().addObserver(wrapper); }

在注释2处将owner和observer封装到LifecycleBoundObserver中,然后在将wrapper添加到mObservers中,mObservers是以observer为key,wrapper为value的map集合,这样可以从集合中通过observer来找到封装它的LifecycleBoundObserver对象。

在注释3处将wrapper作为一个观察者添加到Lifecycle的观察者集合中,这样wrapper就具备了观察Lifecycle生命周期的能力。

LifecycleBoundObserver源码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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); } //注释4 @Override public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) { //注释5 if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } //注释6 activeStateChanged(shouldBeActive()); } @Override boolean isAttachedTo(LifecycleOwner owner) { return mOwner == owner; } @Override void detachObserver() { //注释7 mOwner.getLifecycle().removeObserver(this); } }

从注释3处可以知道LifecycleBoundObserver类型的wrapper对象也是LifecycleObserver的子类,它作为lifecycle的一个观察者,当lifecycle回调生命周期方法的时候,会回调注释4处wrapper的onStateChanged方法。

在注释5处如果Lifecycle生命周期状态是DESTROYED那么就会将该wrapper从map(这里的map就是注释2处添加wrapper的mObservers)中移除掉并结束事件流,这里的移除操作会触发在注释7处的detachObserver方法调用,将wrapper从Lifecycle的观察者集合中移除掉,解除UI层对数据的监听,这样就解决了LiveData在UI层的内存泄漏问题。

如果生命周期没有结束,那么就会继续执行注释6处的activeStateChanged方法,在activeStateChanged中会调用dispatchingValue方法,在dispatchingValue方法中又会调用considerNotify方法处理事件流,considerNotify源码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void considerNotify(ObserverWrapper observer) { if (!observer.mActive) { return; } if (!observer.shouldBeActive()) { observer.activeStateChanged(false); return; } //注释8 if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; //注释9 observer.mObserver.onChanged((T) mData); }

在注释8处mVersion是LiveData中的一个变量,初始值为-1,每次LiveData进行postValue或者setValue时,mVersion都会进行++操作,mLastVersion是观察者ObserverWrapper中的一个变量,只有mLastVersion小于mVersion时才会进行数据分发并且会同步二者的值,否则就结束事件流,这样做可以防止数据的重复多次发送。

在注释9处会调用ObserverWrapper中封装的mObserver(这个就是在UI层通过LiveData的observe方法的第二个参数传递的观察者对象)观察者的onChanged方法,这样在UI层就能接收到数据了。

最后

以上就是专一翅膀最近收集整理的关于LiveData的使用和原理的全部内容,更多相关LiveData内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部