LiveData 理解笔记 - 抽象例子、自动移除 source、Observer 原理

抽象理解:
LiveData链式编程 = 插板
value 改变 = 自身发电,每个插板都能自身发电
addSource = 让此插板通过转换器插上其它插板,这些插板并不能直接连接通电,甚至不能通电,必须在插板A发电时,由插板B的连接转换器设置为(是否随着A发电)
addObserver = 让插板接上电器
lifecycle = 电器,分为好坏状态,可以砸坏,但无法修好

0、
让一个插板连接接电器,电器完好 = addObserver()
1、
发电 -> 电器收到电流 = liveData 成功通知 observer
2、
电器坏了 -> 将电器的插销拔出插板,扔掉电器 = removeObserver() // observer对应的lifecycle被onDestroy()时,移除observer
3、
将此插板插上插板A,并将转换器设置为A发电时,自己也发电 = addSource() = Transformations.map() // map()内部使用addSource()监听source的变化
4、
插板A发电 -> 但因为此插板没有任何用电器,所以电流根本不会走到这里 = // 无 observer 就不监听 source
5、
给此插板接上新的用电器 = addObserver -> 有用电器了 = onActive() = allSource.plug() // 开始观察所有source
6、
插板A发电 -> 此插板转换器让此插板发电 -> 此插板发电 -> 电器受到电流 = // 事件从 source 到 liveData 到 observer 成为事件流

LiveData 理解笔记 - 抽象例子、自动移除 source、Observer 原理_第1张图片

LiveData 理解笔记 - 抽象例子、自动移除 source、Observer 原理_第2张图片

 

@startuml
title: LiveData 自动移除 Observer 原理

class LiveData{
mObservers:Map
observer() //添加
removeObserver() //移除
}

LiveData o-* LifecycleBoundObserver: 内部类
class LifecycleBoundObserver{
observer
lifecycle
onStateChanged()
}
note bottom:封装 lifecycle observer\nDestroyed时,removeObserver()

ObserverWrapper <|-- LifecycleBoundObserver: 观察lifecycle生命周期
interface ObserverWrapper{
}

@enduml

@startuml

title: LiveData 自动移除 Source 原理

class MediatorLiveData{
mSources
addSource() //添加
removeSource() //移除
onActive() // source.plug() -插上所有
onInactive() // source.unplug() -拔掉所有
}

MediatorLiveData o-* Source: 内部类
class Source{
liveData //数据源
observer //监听
plug() //插上
unplug() //拔掉
}

note as N1
plug(){
    mLiveData.observeForever(this);
}
unplug() {
    mLiveData.removeObserver(this);
}
onChanged(){ //liveData 值改变监听
    observer.onChanged();
}
end note
Source .. N1

@enduml

其它测试后结论:

1、LiveData1 监听 LiveData2 事件源,当 LiveData2 对应的View销毁时,LiveData2 内存被释放,没有泄露。

2、若有需求 在 View2 中让 LiveData3 随 LiveData1 触发,那么不要直接 LiveData3.addSource(LiveData1),因为即使View2挂掉,LiveData1依然会通知LiveData3。应该 LiveData1 -> LiveData2 -> LiveData3,并且绑定 LiveData2 与 View2,实现 View2 关闭时 此事件触发链 也销毁的效果。

3、若使用 Kotlin,实际测试:若内部类没有直接使用外部类的 方法/引用,就不会持有外部类引用。

 

你可能感兴趣的:(Android)