重学安卓5-13:通俗易懂 “响应式框架” 使用避坑与封装思路

作品简介
往期回顾专栏目录更新动态优惠政策版权须知
温馨提示:如这是第一次接触《重学安卓》,可通过上述链接快速了解《重学安卓》专栏,获取 专栏目录、试读内容、更新动态 和 发展状况。
截至目前,专栏已对 体系化文章 实施 3310 余次修订,数十位群友告诉我,受专栏启发 亦开启了写作之路。群里不定期会有小伙伴讨论适配问题、分享原创开源库 和 提供内推机会,订阅后可随时进群交流。

·

重要提示
本文假设小伙伴 已实践过 LiveData 基本使用,并 吃过 “被 LiveData 回推脏数据” 的苦
您还没吃过苦,那您先不要着急阅读本文。您得吃过苦,才会有体会。
在您吃够这方面的苦后,您才有机会发现,本文正是专用于解决 “如何找到正确打开方式” 的困扰。
我们绝不通篇贴源码,而是基于广泛的实践和反思,在累积过大量样本 乃至足以排除掉所有干扰信息后,点到为止揭露 “造成该现象的缘由” 和 “对症下药的解法”,方便您理解其存在意义,乃至笃信使用项目中。
关于具体源码,请参见文中提及的配套开源项目。

前言

19 年,笔者就 “LiveData 自动回推脏数据” 现象发行了《LiveData 数据倒灌》篇

4 年间,Kotlin Flow 乃至 StateFlow、SharedFlow 等框架陆续问世,开发者经由这些简洁易用框架,不知不觉融入 “响应式编程” 开发,

经过大量实践和检验,笔者留意到 “响应式编程” 框架普遍存在的漏洞,以及造成这些漏洞的根源,

故这期以 LiveData 为例,从 “问题场景、隐患根源、出路分析” 3 方面入手,拆解 “响应式编程” 框架使用时所需注意的细节,和封装时可借鉴的原则和思路,

相信阅读后你会耳目一新。

文章目录一览

  • 前言
  • LiveData 框架使用
  • 场景 1:页面内数据回推
  • 场景 2:左右分栏数据回推
  • LiveData 隐藏坑
  • 场景 3:使用多个 LiveData
  • 场景 4:三级页面数据回推
  • 场景 5:消息连发
  • 造成坑的根源
  • LiveData 由来
  • 响应式编程的状态和事件
  • 响应式编程的漏洞
  • 破局方案
  • 探索 BehaviorSubject 的合适承担者
  • 探索 PublishSubject 的合适承担者
  • 确保能消费到,且只消费一次
  • 综上

LiveData 框架使用

场景 1:页面内数据回推

例如最简单的网络请求场景:

在页面发起请求,经由 ViewModel 的中转和逻辑处理,并将结果通过 LiveData 返回:

img

场景 2:左右分栏数据回推

又如官网提到的 SplitView —— 平板电脑 “设置页面” 左右分栏的场景,左侧是 ListFragment,右侧是 DetailFragment,

那么此时可在作用域为 Activity 的 SharedViewModel 中,安排一个用于页面通信的 LiveData,然后从 ListFragment 向 DetailFragment 发送消息,这样 ListFragment 点击了哪个 Item,DetailFragment 随即就能响应和显示哪个 Item 的详情,

img

LiveData 隐藏坑

场景 3:使用多个 LiveData

场景 1 是假设开发者在一个页面中只用一个 LiveData,所有控件都只在该 LiveData 中响应和渲染,

但现实中极可能因为各种因素,在一个页面中引入多个 LiveData,并且开发者误把某一控件实例存在于多个 LiveData 的 Observer 回调中,如此便埋下隐患,

img

如图,LiveData_B 的注册晚于 LiveData_A,二者回调中皆有 tvTitle 实例在,此时通过 LiveData_A 给 tvTitle 回传一个新数据,然后旋转屏幕使页面重建,

根据用户预期,页面重建后理应展示最后一次数据,也即 LiveData_A 给 tvTitle 回传的新数据,但现实是,由于 LiveData_B 的注册晚于 LiveData_A,且 LiveData 存在粘性设定,因而页面重建后 tvTitle 最终响应和显示的是 LiveData_B 回推的 “过时数据”,造成与用户预期不一致,

创作时间: