上回在不贴源码能说明白Android LiveData原理吗?(一)中说到,在LiveData内部收到LifecycleOwner
的生命周期变化时,会根据是否是active状态来通知数据更新,并且在owner的DESTROYED
状态时,移除掉LifecycleOwner
和Observer
的引用,来避免内存泄漏,这背后又隐藏了哪些细节呢?
SafeIterableMap
在owner的生命周期变化为DESTROYED
时,对应的Observer
需要从集合中remove掉,但同时可能LiveData
正在遍历Obervers
集合,并且试图更新最新的data到Observer
。
如何解决这个问题,Google实现了一个SafeIterableMap
,在迭代过程中支持修改数据的集合。并且还写了一个子类 命名为 FastSafeIterableMap
??? 这让我想起了Java中的Fast-Fail
机制,这究竟是江湖恩怨还是私人情仇?
话说回来,这个SafeIterableMap
并不是真正的Map,而是用双向链表+泛型<K,V>,模拟了Map的操作,并且实现了一个可以在迭代的同时支持remove数据的Iterator,命名为 IteratorWithAdditions
。
如何安全的移除LiveData的观察者
IteratorWithAdditions
有一个current指针指向迭代的当前对象,IteratorWithAdditions
在迭代数据的同时,也负责让current对象支持remove操作,如何实现?
每次创建Iterator
对象,开始迭代时,会将这个Iterator
添加到一个WeakHashMap
集合中,在Observer
需要remove时,首先遍历处于迭代过程中的Iterator
,判断每个Iterator
的current对象是否就是要remove的对象。
如果是,将这个迭代器的current指针,指向前一个对象,这时,上一个对象被重复迭代一次,但是在更新数据的时候LiveData
会判断该对象是否已经更新过,所以重复迭代一次并不会发生数据重复更新。而要remove的对象 就可以在current指针指向它之前,也就是说接收到数据更新的通知前,从SafeIterableMap
中移除掉。
当LiveData
移除了Observer
引用后,还要从LifecycleOwner
中移除Observer
,因为Observer
还观察了owner的生命周期。具体处理LifecycleOwner
的生命周期事件的是一个代理类LifecycleRegistry
,在其中就用到了SafeIterableMap
的子类,FastSafeIterableMap
,来保存观察生命周期的Observer。
onActive()和onInactive()
LiveData
还会记录活跃的观察者数量,当LiveData
的观察者数量从无到有时,便会回调onActive()
方法,可以在这里开始请求数据,当观察者数量变为0时,会回调onInactive()
方法,在这里处理和数据连接的断开,或者说可以在这里取消一些不再需要的网络请求。