重学安卓2-6:耳目一新 Jetpack MVVM 精讲

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

前言

最近后台时而收到读者留言,说能否出一期 Jetpack MVVM 精讲,以及配套一份简练案例,好把玩把玩、感受感受、加深 MVVM 印象。

答案是肯定的。

面向标准化开发已成现实

金九银十,相信不少读者在抓紧机会面试。

Android 市场已今非昔比。过去迫于招人压力,应试者只需了解四大组件、视图、网络请求,即可谋得一份满意工作。

现如今,Jetpack 架构组件及 “标准化开发模式” 确立,预示 Android 开发已步入成熟阶段:

许多 “样板代码” 不再需开发者手写,而是可通过 “模版工具” 自动生成,在取缔繁杂耗时重复工作同时,避免因 “人工操作疏忽” 造成难以排查、不可预期错误

这十分符合企业利益,因而面试官招人时,也更加看重应试者对架构组件 —— 至少是 MVVM 理解程度。

像 “解耦” 等含糊其辞说法,不再为面试官认可,稍有 MVVM 经验面试官,都会请你举例说明,好证实你对 MVVM 确有深入理解,能自然而然写出标准化、规范化代码,能迅速适应各公司自制 “自动化模版工具”。

本文目标

本人拥有 3 年 “移动端架构” 践行和设计经验,领导或参与团队 “重构” 中大型项目多达十数个,对 Jetpack MVVM 架构在 “确立规范化、标准化开发模式,以减少不可预期错误” 所作努力,有深入理解。

因而本文目标,就是结合前几期我们分别 “深入浅出” 介绍的 Lifecycle、LiveData、ViewModel、DataBinding 来融汇贯通演绎一下:

作为 “应用开发骨架” 的 “标准化状态管理框架”,究竟为快速开发过程中 “减少不可预期错误” 做了哪些努力。

不同于 “东拼西凑、人云亦云、徒添困扰” 网文,愿意将标准化开发模式 深度思考知识实战反思经验 无保留分享,全网仅此一家。这样文章可以说 看一篇、少一篇,因此,就算不去 hold 住面试官,也请务必跟随本文脚步,将 Jetpack MVVM 来龙去脉过一遍。

文章目录一览

  • 前言
  • 面向标准化开发已成现实
  • 本文目标
  • Jetpack Lifecycle
  • Lifecycle 存在前的混沌世界
  • Lifecycle 为什么能解决上述这些问题?
  • Jetpack LiveData
  • LiveData 存在前的混沌世界
  • LiveData 为什么能解决上述这些问题?
  • LiveData 有个坑需要注意
  • Jetpack ViewModel
  • ViewModel 存在前的混沌世界
  • ViewModel 为什么能做到这几点?
  • Jetpack DataBinding
  • DataBinding 存在前的混沌世界
  • DataBinding 就是来解决这些问题
  • 综上

Jetpack Lifecycle

Lifecycle 的存在,主要为了解决 “生命周期管理” 一致性问题

Lifecycle 存在前的混沌世界


Lifecycle 面市前,“生命周期管理” 纯靠手工维持,这容易滋生大量一致性问题。

例如跨页面共享 GpsManager 组件,需要分别在每个宿主 Activity 的 onResume 和 onPause 中 手动激活和叫停

那么 随着宿主 Activity 增多,这种手动操作埋下的 “一致性隐患” 就会指数级增长

一方面,凡需手工维持,开发者皆易疏忽,特别是工作交接给其他同事时,同事并不能及时注意到这些细节。
另一方面,分散的代码不利于修改,日后除了激活、叫停,若有其他操作补充,则每个宿主 Activity 都需额外书写一遍。


Lifecycle 为何能解决上述这些问题?


Lifecycle 通过 “模板方法模式” 和 “观察者模式”,将生命周期管理的复杂操作,全在 LifecycleOwner(如 Activity、Fragment 等 “视图控制器” 基类)中封装好,默默在背后为开发者运筹帷幄,

开发者因而得以在 “视图控制器” 子类中只需一句 getLifecycle().addObserver(GpsManager.getInstance) ,优雅完成 “第三方组件” 在自己内部对 LifecycleOwner 生命周期 “感知”。


除解决一致性问题,这么做还 顺带提供其他 2 个好处

1.规避为 “监听状态” 而注入 “视图控制器” 做法

为监听状态,传统做法是,将 Activity 作为方法参数手工注入,这埋下 “内存泄漏” 隐患 —— 因为团队新手容易因 “这有个 Activity 实例”,而在日后误将其上升为成员变量,并依赖给组件中其他成员。

现如今,我们可直接在组件内部 “点到为止” 监听 LifecycleOwner 状态,从而规避这种不恰当使用。

2.规避为 “追溯事故来源” 而注入 “视图控制器” 做法

发生事故时,传统 追溯事故来源 方式,同是向方法参数直接注入 Activity,这再次埋下 “内存泄漏” 隐患。现如今,三方组件实现 DefaultLifecycleObserver 即可在 “生命周期回调” 方法作用域中 直接根据 LifecycleOwner 参数得知事故源。

如这么说无体会,详见《为你还原一个真实的 Jetpack Lifecycle》 中提供的 GpsManager 案例,本文不再累述。

Jetpack LiveData

LiveData 的存在,主要为了 新手老手都能不假思索遵循 “通过唯一可信源分发消息” 标准化开发理念,以便快速开发过程中 “难追溯、难排查、不可预期” 问题发生概率降低到最低。

LiveData 存在前的混沌世界


LiveData 面市前,我们在 “网络请求回调、跨页面通信” 等场景分发消息,多是通过 EventBus 或 Java Interface 完成。

那这造成什么问题?首先,EventBus 等 “消息总线” 只是纯粹传话筒,它 缺乏上述 “标准化开发理念” 约束,那么人们使用该框架时,容易因 “去中心化” 滥用,造成诸如 “毫无防备收到预期外、不明来源推送”、拿到过时数据、事件源追溯复杂度放大至 n²

且,EventBus 本身缺乏 Lifecycle 加持,存在生命周期管理一致性问题。这是 EventBus 硬伤,也是我拒绝使用 EventBus 最主要因素。

如对上述状况无体会,可具体参考我们在 《LiveData 鲜为人知 身世背景 和 独特使命》 中提供的 “播放器状态全局通知” 案例。

LiveData 为何能解决上述这些问题?


创作时间: