LiveData 數據倒灌:別問,問就是不可預期

前言

很高興見到你!我是《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 的 “延遲自動清理消息” 的設計,均屬於本人獨立原創的成果,本人對此享有最終解釋權。

任何個人或組織在引用上述內容時,須註明原作者和出處。未經授權不得用於洗稿、廣告包裝等商業用途。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章