Jetpack 简介
JetPack 不是一个库。更多的是Google的一个态度。早些时候,Android开发者基本都是被放养的。生态基本全靠自建,代表有Square全家桶,Glide,Google自己也肯定是出力的,只不过并没有明确Android开发的几个大方向。比如Support lib 经常自己打自己脸。一会推这个API, 一会又Deprecate那个API,再比如标准库中Camera API,苦不堪言。Google自家的几个库又并不是那么好用,比如Volley,当然Google也有许多优秀的库,比如ExoPlayer,FlexboxLayout,RecyclerView等等。自Google IO 17 开始。官方终于开始管理这个混乱的Android开发环境,推出 Architecture Component,包括了大家一直期待的O®M库 Room,和生命周期管理工具ViewModel/LiveData。IO 18 更是加大力度,将Support lib改名 AndroidX重新1开始,并且将所有Google 认为是正确的Practice 集中在一起,帮助开发者来简单,高效地进行Android开发。而这所有的东西现在,统称 JetPack。JetPack 目前开始基本就明确了Google的大方向,JetPack里有的,Google 将会继续维护并增加新特性。 JetPack里没有的,除Retrofit/OkHttp/RxJava 等一些优秀的第三方库以外,Google要么不明确支持,要么早晚被Deprecate。所以如何看待JetPack?JetPack是必须使用的,但是不是必须所有组件都使用,原提问中提到了Paging和WorkManager这两个仍在Alpha 阶段的两个库,但是JetPack包含的太多太多了。Fragment/AppCompatActivity你已经会用。这些都在JetPack里。LiveData/Room/ViewModel这些去年推出的优秀第一方组件,你也应该使用,这些也在JetPack里。我个人觉得,Google 早早就应该这样统一管理Android的开发生态,从17,18的成果来看,亡羊补牢,为时不晚。
以上摘抄字如何看待Android的Jetpack这一系列库?
Jetpack 包含了一系列内容,但是这里并不打算把每一个内容都做介绍,主要是介绍架构 - Architecture部分
帮助开发者设计稳健、可测试且易维护的应用
- Data Binding(数据绑定):属于支持库可使用声明式将布局中的界面组件绑定到应用中的数据源
- Lifecycles:管理 Activity 和 Fragment 生命周期
- LiveData:是一个可观察的数据持有者类。与常规observable不同,LiveData是有生命周期感知的。
- Navigation:处理应用内导航所需的一切
- Paging:一次加载 or 按需加载 & 显示小块数据
- Room:帮助开发者更友好、流畅的访问SQLite数据库。
- ViewModel:以生命周期感知的方式存储和管理与UI相关的数据。
- WorkManager:调度预期将要运行的可延迟异步任务。(即便应用程序退出 or重启)
Google官方推荐的应用架构
Architecture 的内容也并不打算全部介绍,Navigation以及WorkManager 会直接忽略。
Android 架构
MVC、MVP、MVVM这些模式是为了解决开发过程中的实际问题而提出来的,目前作为主流的几种架构模式而被广泛使用。
前言
在写这篇文章之前,我本以为这一片应该是最容易完成的,必须不需要理解源码,只需要配上两张图然后介绍一下就完工的,但是在实际我却多次想要放弃对于对MVC、MVP、MVVM介绍,以前对于这三种架构方式也有所了解,但是没有深入去研究,本想趁着这次写博客的机会在深入研究一下,可是查阅了很多资料之后,我的困惑却越来越多,因为不同的人,不同的文章对于这三种架构的描叙都还不一样,有的甚至是南辕北辙,配图更是乱七八糟。
最后去除一些明显的错误,剩余的导致这种情形的原因大致分为两类:
- 开发语言(java,js.oc,.net)与使用系统(android ,ios ,window)的原因。在两个不同的系统里面对于同一个架构实现存在差异,导致开发人员对一架构的理解跟另一系统的开发人员理解存在差异。
- 时间的原因,时代在快速的发展,例如MVC是在上世纪70年代末提出的,那个时代的MVC跟当前时代的MVC 存在差异。
MVC
这张图比较全面的描绘了MVC架构的信息,你如果在网络上查询MVC 你大概率会遇到下面接种
操作如下:
- 用户在视图 V 上与应用程序交互
- 控制器 C 触发相应的事件,要求模型 M 改变状态(读写数据)
- 模型 M 将数据发送到视图 V ,更新数据,展现给用户
我不知道是不是久远以前的MVC 就是如此简单,我倾向认为是作者只是简化了MVC,实际上现在以当前的ui业务的复杂性,controller 应该是可以主动控制View的显示,例如上传数据的时候要求View显示一个进度条等等,而非View的显示仅仅取决于Model提供的数据,大家可以结合自己的实际工作经验体会一下。这也许就是理论与现实之间的距离。
在MVC 模式中View 是知道Model的存在,View 可以主动的直接从Model 里面获取数据,这一点是MVC 与MVP最大的区别。
MVC的侧重点在于模型(M)与视图(V)之间是可以互相感知这一点,其余的都是细枝末节,由于这些细节的不同,不同的文章介绍的MVC模式就各有不同,例如于通知视图数据变化的方式,1 Model 通知View,2 Controller 通知View。有的文章介绍的时候是采用的前者,有的介绍的时候是才有的后者。以android 开发为例子,我一般都是controller 修改modle,然后controller 通知View 数据变更,根据这两种通知的不同又可以化分为被动模式与主动模式
被动模式
在被动模式中, Controller是唯一操作Model的类. 基于用户的响应事件, Controller通知Model更新数据. 在Model更新后, Controller通知View更新UI, View从Model中获取数据.
主动模式
在主动模式中, Controller不是唯一操作Model的类, Model存在自更新机制. 在更新数据时, Model层使用观察者(Observer)模式通知View和其他类. View实现观察者的接口, 在Model中, 注册成为观察者, 接收通知。当Model层发生数据更新时, 告知全部观察者. View从Model中更新数据.
说了这么多,还没有说道MVC 这三层究竟代表了什么:
理论上:
View :视图层,也就是我们的UI
Controller:控制层,处理UI逻辑以及同步逻辑
Model : 从网络或者数据库 获取数据或者上传数据。
实际上:
-
被阉割的View ,我们说View 是负责展示UI的,理论上我们的所有UI 都应该定义在View 层,这里以android
为例子,当我们想弹出一个对话框,或者是修改某一个控制的位置或者是做一些动画,这些实际上我们没有办法定义在View层,因为android的View层是通过xml文件定义的,程序员没有办法动态的修改这个xml文件,如果你想修改布局那就只可以在controller 里面修改。这是android 天生的缺陷,View层的功能太弱,就像被阉割了一样。如果android 可以向flutter或者是ios那样可以方便的通过代码控制最终生成的ui页面,那么View层就可以得到大大的提升。此时View层就可以根据不同的情形显示不同的ui,不必controller的过多参与这个过程。
可能有的初学者会说android 也可以通过代码布局ui啊,对此我只想除非迫不得已,没人会喜欢用android的代码布局。 2 -
臃肿的Controller ,上面说了View 层被阉割了,这些被阉割的功能,最终都被放到了activity里面,此时activity
就既是View 又是Controller ,有的时候页面的ui逻辑非常复杂在加上业务逻辑,这就导致了Controller 的极大臃肿。 -
正常的Model. 这个没有什么好说的。
这里就又显示出来了理论与现实之间的距离,MVC的理论挺好,但是我办不到啊,办不到的原因是什么,这就跟具体的语言或者是系统由关系了,我不到ios或者是其他的平台有没有这种问题,一个被阉割,一个太臃肿。
而且MVC中的V需要同时跟M,C打交道,打交道的对象越多,越不好控制,有的时候会导致很多的问题,这里让View与Modle 不要之间交互,这样降低View的复杂度。
所以为了解决上面的两个问题,就有了MVP模式
MVP
MVP 是MVC的升级版,减去了View与Modle之间的直接交流。
View : View层,定义UI的展示逻辑。以android 为例,View 就是xml布局文件,原生与自定义控件,以及Activity ,是对android MVC 中的V的增强版。
P:表现层,P 层逻辑性这里称之为P Logic。例如,某个文本内容不能为空,当某个事件发生时获取界面上哪些内容,以及要求View 展示一个进度条或者是一个对话框(至于这个进度条或对话框是什么样子的,那View层的问题,P层只是要求View层展示或则隐藏),这都属于 P Logic。应该指出,P Logic应该是抽象于具体UI的,它的本质是逻辑,可以复用到任何与此逻辑相符的UI。P Logic 还包含同步逻辑,就是通知View 层数据变化了,并把新的数据传递给View层。
M: 业务层,处理的是业务逻辑,主要是操作数据库或者访问网络。
用户界面的3大问题:状态 (State) , 逻辑 (Logic) ,同步 (Synchronization)
-
状态 (State))
状态是用户界面最关心的问题之一。状态是用户界面数据的当前快照,例如一个具有选择删除功能的列表,那么可能需要记录用户当前有没有选中要删除的Item ,以及哪些item 被用户选择了,在比如一个输入框我们需要记录用户的当前输入等等。 用户界面包含的状态越多, 则用户界面越复杂。 -
逻辑 (Logic)
用户界面往往包含界面逻辑,例如维护文本框、组合框或者有数据的时候显示数据,没数据显示一个特定的图片,用户界面中这种逻辑越多,则用户界面越复杂。 -
同步 (Synchronization)
用户界面通常需要和业务组件协作,因此用户界面需要在界面元素与业务对象之间同步数据,如果用户界面包含的同步任务越多,则用户界面越复杂。
这三大问题与用户界面的关系如下图:
表现设计模式 (Presentation Design Pattern)
表现类 (Presenter) ,用来消化用户界面中复杂的逻辑,数据和同步的问题,从而使得用户界面变得简单明了。根据这个类承担责任的多少,决定了表现设计模式的类型,可能是 SC , PV , PM 等,也就是说,这个类的成熟度决定了它将是那种设计模式。
在实际实现中MVP 也可以有多种实现方式。
有用的缩写
一
android 中最常见的就是 ,P层与V 层彼此持有对方的引用,通常的时候会像定义两个接口IView与IPrenster ,然后在定义两个类View与Prenster 分别实现上述连个接口,这样方便复用。但是这样有一个巨大的缺陷,就是机会每一个页面都需要两个接口,这样整个项目会增加非常多的类。
二 被动视图
- 状态在视图中保存
- 所有的界面逻辑都被包含在表现类中
- 视图和业务模型完全独立,这种情况下需要一些在业务模型和视图之间进行同步数据的工作
- 表现类关注视图
- 视图不关注表现类
此时 p包含V的引用,但是V不包含P的引用,一般这种情形下P层需要在V内注册观察者,V层有ui时间的时候会通过P注册的观察者通知P层。这样有一个好处就是View 层可以完全独立,测试的时候可以单元测试。
被动视图在android 里面用的比较少,不知道其余的系统中是否用这种应用
三 表现模型 (PM)
- 表现类包含逻辑
- 表现类包含状态
- 表现类代表抽象的用户界面
- 表现类不关注用户界面
- 视图关注表现类
- 视图与业务模型完全隔离
此时V包含P的引用,但是P不包含V的引用,一般这种情形下View 需要在P内注册观察者,当数据变换的时候P通过观察者通知V层。
android Jetpack 里面的 ViewModel 就是用的这个模式。什么ViewModel 不是MVVM,这里介绍的是MVP 啊。MVVM 实际就是MVP+Databing 但是实际上android 的databing 根本没人用,所以可以直接将ViewMoel 看成是Prenster 。 此时也不需要单独建立一个View层直接将Activity 看成View 层就可以了。
注: 这里将State 保存在了P层,但是实际应用中也可以放到V层。
MVVM
从以上的架构图中,我们可以很清晰的梳理出各自的分工。
-
View层:视图展示。一android为例子,View 包含xml 布局,Activity 以及系统提供的View以及自定义的View. 。对于xml 而言,android通过DataBinding框架扩充的xml的功能,使得开发者可以在xml 布局里面绑定数据以及使用一些简易的代码。
ViewModel层:视图适配器,实质跟MVP里面的P没什么区别。
-
Model层:数据模型与持久化抽象模型。数据模型很好理解,就是从服务器拉回来的JSON数据。而持久化抽象模型暂时放在Model层。
-
Binder:MVVM的灵魂,可惜在MVVM这几个英文单词中并没有它的一席之地,它的最主要作用是在View和ViewModel之间做了双向数据绑定。如果MVVM没有Binder,那么它与MVP的差异不是很大。
这里给出的也仅仅是理论上的一种MVVP 架构,在实际操作中很多时候会根据自身的情况加以修改,进而衍生出很多的变体。
例如 我是可以使用DataBing 将View与Model绑定在一起,而不是将View与ViewModel 绑定在一起。再比如 有的时候又会对Model 层扩展,添加一个DataContrller 层,DataContrller 管理多个数据源(网络,数据库,文件等等),当前在MVP里面也可以添加一个DataContrller 层。所以理论与实际应用总是有差别的,希望大家不必太在意这些细节,而更多的关注架构里面的思想。
补充说明
ios 里面也有MVC 与MVP 架构,但是查阅的一点资料显示ios的MVC架构等价于android 的MVP.
苹果的MVC
可以看到苹果的MVC 在android里面就是MVP.
参考文章
苹果的mvc框架
微软的mvc框架
MVP(SC),MVP(PV),PM,MVVM 和 MVC 表现模式架构对比
完全解析Android项目架构
设计框架(MVC、MVP、MVVM、VIPER)的演化说明总结
.Net平台-MVP模式初探