前言
很高興見到你!我是《Jetpack MVVM Best Practice》作者 KunMinX。
今天提到的 “數據倒灌” 一詞,是我爲了方便理解和記憶 “頁面在 ‘二進宮’ 時收到舊數據推送” 的情況,而在 2019 年 自創並在網上傳播的 對此類現象的概括。
它主要發生在:通過 SharedViewModel + LiveData 的組合 來解決頁面通信的場景。
本文的目標
由於本文的目標主要是來介紹 官方 Demo 現有解決方案的缺陷,以及經過 1 年迭代的完美解決方案,
所以我假設在座的諸位 對最基本的背景緣由有一定的瞭解,知道:
爲什麼 LiveData 默認被設計爲粘性事件
爲什麼 官方文檔 推薦使用 SharedViewModel + LiveData(文檔沒明說,但事實上包含三個關鍵的背景緣由)
乃至爲什麼存在 “數據倒灌” 的現象
以及爲什麼在 “頁面通信” 的場景下,不用靜態單例、不用 LiveDataBus
如果對於這些前置知識也尚不瞭解,可結合個人興趣前往《LiveData 數據倒灌 背景緣由全貌 獨家解析》查閱,此處不再累述。
現有解決方案及各自缺陷
在《Jetpack MVVM 精講》中我分別提到了 Event 事件包裝器、反射方式、SingleLiveEvent 這三種方式來解決 “數據倒灌” 的問題。它們分別來自上文我們提到的外網、美團的文章,和官方最新 demo。
但正如我在《Jetpack MVVM 精講》介紹的,它們分別存在如下問題:
Event 事件包裝器:
對於多觀察者的情況,只允許第一個觀察者消費,這不符合現實需求;
而且手寫 Event 事件包裝器,在 Java 中存在 null 安全的一致性問題。
·
反射干預 Version 的方式:
存在延遲,無法用於對實時性有要求的場景;
並且數據會隨着 SharedViewModel 長久滯留在內存中得不到釋放。
·
官方最新 demo 中的 SingleLiveEvent:
是對 Event 事件包裝器 一致性問題的改進,但未解決多觀察者消費的問題;
而且額外引入了消息未能從內存中釋放的問題。
UnPeekLiveData 特點
UnPeekLiveData 通過 獨創的 “延時自動清理消息” 的設計,來滿足:
1.消息被分發給多個觀察者時,不會因第一個觀察者消費了而直接被置空
2.時限到了,消息便不再會被倒灌
3.時限到了,消息自動從內存中清理釋放
4.使非入侵的設計成爲可能,並最終結合官方 SingleLiveEvent 的設計實現了 遵循開閉原則的非入侵重寫。
並且 UnPeekLiveData 提供了構造器模式,可通過構造器組裝適合自己業務場景的 UnPeekLiveData。
零入侵設計 | 延時自動清理消息 | Builder 構造器 |
---|---|---|
PS:非常感謝近期 hegaojian、Angki、Flynn、Joker_Wan 等小夥伴積極的試用和反饋,使得未被覺察的問題 被及時發現和納入考慮。
JCenter 依賴
詳見 GitHub:https://github.com/KunMinX/UnPeekLiveData
License
本文以 CC 署名-非商業性使用-禁止演繹 4.0 國際協議 發行。
Copyright © 2019-present KunMinX
文中提到的 對 “數據倒灌” 一詞及其現象的概括、對 Event 事件包裝器、反射方式、SingleLiveEvent 各自存在的缺陷的理解,以及對 UnPeekLiveData 的 “延遲自動清理消息” 的設計,均屬於本人獨立原創的成果,本人對此享有最終解釋權。
任何個人或組織在引用上述內容時,須註明原作者和出處。未經授權不得用於洗稿、廣告包裝等商業用途。