跳至主要內容

01.Jetpack我们先从MVVM开始讲起


Jetpack我们先从MVVM开始讲起

在开始Jetpack相关的课程之前,我们先从MVVM开始讲起。google推荐我们的应用架构是MVVM。

图片描述
图片描述

原连接地址:应用架构指南open in new window

为了达到实现这个架构,我们应该学习什么知识。Jetpack各组件充当着什么角色。

什么是MVVM

MVVM从MVC开始讲起

MVC

以前我们的Android开发,开始流行的是MVC结构,这套东西其实是从后台里借鉴过来的,特别是PHP,连命名都按这个规范。

图片描述
图片描述
图片描述
图片描述

那这几块负责什么职责呢?

图片描述
图片描述

我们先是认清楚了各个模块负责什么东西

然后再来看看这个MVC组件之间的经典合作

图片描述
图片描述

PS:注意,是经典合作。不是必须这样做,这只是其中一种合作方式。

在不同的项目开发里面,分别有不同的内容充当MVC。

那在Android里是什么充当View,什么充当Model,什么充当Controller呢?

View:Acitivity(View)、Fragment(View)视图,在android里xml布局转成View后,加载到了Activity/Fragment里了。

Controller:Controller对应着Activity/Fragment,绑定UI,处理各种业务。

Model:数据的获取,存储,更新,domain

图片描述
图片描述

优点

view与model隔离,view换了,model不影响。model换其他的数据源,view层也不受影响。一个view可以连接多个model,有些model可以复用。比如说你这个页面需要用户信息,另外一个界面也需要用户信息。

缺点

这里我们主要指Android上的缺点,不适合在Android开发上使用。在Android开发中,View的相关内容和Controller都写到一起了,会让Activity/Fragment越来越臃肿

MVP

于是大家都觉得MVC套在Android上不好。VC的代码会越来越多,如果要处理复杂的逻辑,Activity的代码上千上行。于是大家开始剥离VC里的代码。

这个用起来爽了很多,Activity的代码量也没这么多了。

大量的逻辑代码抽取到了Presenter层。

同学们可以学习一下我们的两个项目

《喜马拉雅FM电台》open in new window《恰饭联盟》open in new window

这两个项目就是MVP的架构

  • View:Activity、Fragment
  • Presneter:逻辑层
  • Model:数据处理

在MVP架构中,我们设计到的内容是调用逻辑层的方法和更新UI,这是最简单的。

问题点就是:怎么调用逻辑层的方法呢?怎么通知UI更新呢?

View层持有Presenter层的引用或者通过管理类管理Presenter,总之View可以直接拿到Presenter,这样子,View就可以调用Presenter里的方法了。比如说Presenter你给我获取一个这个页面的分类。

Presenter层如何更新UI呢?当View层去获取/创建Presenter的时候,把接口给到Presenter,比如说Presenter层获取到分类以后,通过接口更新UI即可。

这样子,我们这个来回就完事了。Presenter层则通过Model层去拿数据。

图片描述
图片描述

优点

剥离了View和Controller,解决了复杂的业务Activity过于庞大的问题

缺点

  • 更新UI需要主意线程,UI控件是否已经销毁(在用户可视的生命周期范围内更新UI即可)

    假如我们去请求一个数据,这个时候请求是耗时的,数据回来了,可是界面已经被用户关掉了,数据回来以后,我们得判断UI控件是否还存在。

  • 如果多个地方使用到同一个Presenter,可能会存在一些用不上的接口

    还是有的,我们在喜马拉雅FM电台里就有体现出来。

    比如说我们的播放器逻辑层PlayerPresenter,我们对应需要通知UI的接口有开始播放,暂停播放,缓冲中,播放失败,下一首,上一首,播放模式改变...

    如果我们多个地方使用到这个Presenter。比如说首页,详情页面,播放器页面。播放器页面使用这个Presenter实现这个接口没问题,都用得上。可是我的首页,只需要暂停播放和播放呀,其他的状态并不需要。

    一大堆用不上的接口

图片描述
图片描述

改造MVP

原则

  • 减少/不依赖View
  • 数据驱动UI,数据变化,UI自动更新

目的

  • View不与Presenter直接关联
  • 确保数据在主线程更新UI
  • 感知View的生命周期
    • 可见的生命周期范围数据更新则更新UI,否则不更新UI
    • View不可见时时候,暂停某些不必要的操作

MVVM

经过前面两个框架的探索,google和众多开发者找到了Android应用开发的最佳实践,更适合Android开发的一个架构MVVM

图片描述
图片描述

View:指我们的Activity/Fragment

ViewModel:ViewModel

Model:Repository(数据的操作、domain)

MVVM 最简单模型

我们先不使用Jetpack的各个组件,我们纯手功实现一个MVVM框架。

分层:

View:我们的Framgnet/Activity

ViewModel:ViweModel是为View管理数据的,也负责业务逻辑处理

Model: 对应Repository、比如说文章的ArticleRepository、

MVVM要点:

  • 尽量不要依赖View
  • 模型驱动界面、独立于View对象和组件,不受View/组件生命周期影响

要求:

  • 解决MVC的问题
    • 我们把逻辑拆分到各个ViewModel里,Activity/fragment只负责UI的绑定和UI事件监听
  • 解决MVP的问题
    • View层持有ViewModel的引用,调用里面的方法。
    • 监听ViewModel里的数据更新UI,你需要什么监听什么,而不是像Presenter全部通知到各个View层,需要View层实现所有的接口

Jetpack与MVVM

  • ViewModel 对象为特定的界面组件(如 Fragment 或 Activity)提供数据,并包含数据处理业务逻辑,以与模型进行通信。例如,ViewModel 可以调用其他组件来加载数据,还可以转发用户请求来修改数据。ViewModel 不了解界面组件,因此不受配置更改(如在旋转设备时重新创建 Activity)的影响。

  • LiveData 是一种可观察的数据存储器。应用中的其他组件可以使用此存储器监控对象的更改,而无需在它们之间创建明确且严格的依赖路径。LiveData 组件还遵循应用组件(如 Activity、Fragment 和 Service)的生命周期状态,并包括清理逻辑以防止对象泄漏和过多的内存消耗。

  • Room是一个对象映射库,可利用最少的样板代码实现本地数据持久性。在编译时,它会根据数据架构验证每个查询,这样损坏的 SQL 查询会导致编译时错误而不是运行时失败。Room 可以抽象化处理原始 SQL 表格和查询的一些底层实现细节。它还允许您观察对数据库数据(包括集合和连接查询)的更改,并使用 LiveData 对象公开这类更改。它甚至明确定义了解决一些常见线程问题(如访问主线程上的存储空间)的执行约束。

推荐做法

MVVM里的ViewModel,也会随着业务的复杂度会变得很臃肿,因为我们把逻辑和数据都写在了里面。所以这里建议大家:

如果是大型的项目,以bean类来拆分ViewModel,本质上一个bean类,的操作应该是增删改查,再加上逻辑处理。 这个子ViewModel会小一点。

比如说:你一个用户中心,除了用户信息,还有这个用户所写的文章,分享,回答的内容。如果这个View,只对应着一个ViewModel,那么你这个ViewModel会比较大。如果你拆开来UserViewModel,ArticleViewModel,ShareViewModel,QAViewModel这样会不会小一点呢?

通过ViewModelProvider来创建和管理ViewModel,它是保存在对应的owner里(ViewModelStore),也就是说,如果你要共享数据,比如说多个fragment,用同一个ViewModel,那么你最好使用他们所依附的Activity对应的ViewModel。

当然啦,这些都是推荐做法,并不是绝对的规则。所以google的文档在最前面说了这么一句话:

If you already have a good way of writing Android apps that follows the common architectural principlesopen in new window, you don't need to change it.

相关课程

图片描述
图片描述

Jetpack我们从MVVM开始讲起open in new window