使用Android架构组件开发MVVM模式的应用

栏目: 编程工具 · 发布时间: 7年前

内容简介:早在17年的Google IO大会上,Google就非常隆重的介绍了以MVVM和我们熟知的MVC、MVP类似,都属于一种架构模式,它的全称是

早在17年的Google IO大会上,Google就非常隆重的介绍了以 LiveDataViewModel 为主的Android架构组件。本文主要通过介绍 LiveDataViewModel 这些组件的概念,来实现一个MVVM模式的应用。

MVVM

MVVM和我们熟知的MVC、MVP类似,都属于一种架构模式,它的全称是 Model–View–ViewModel 。在MVP这类模式当中,一个事件流一般是从View开始,经过P,最后交给M进行处理,但当P处理结束后,可以再通过P或者发布事件的方式再更改V。图示如下:

使用Android架构组件开发MVVM模式的应用

简单来理解的话,MVVM可以看作MVP的升级版本,View的变动,自动反映在 ViewModel,反之亦然。这种行为俗称双向绑定,双向绑定的实现方式很多,本文不做列举。双向绑定带来的最大好处是,代码量变少,重用性更高。

使用Android架构组件开发MVVM模式的应用

接下来,我们详细看一下MVVM拆解开来的三个部分:

  • Model

Model代表了一个应用的数据和业务逻辑层。该层的推荐实现形式是通过对外提供可观察的数据对象,以便与ViewModel或任何其他观察者/消费者完全分离。在 Android 应用中,常见的可观察对象如Rxjava中的Ovserable,再比如我们今天要讲到的Android架构组建中的LiveData。

  • ViewModel

ViewModel负责与Model层交互,并且还需要将Model层的数据以可观察的对象形式提供给View。该层的一个重要实现准则是将它与View分离,即ViewModel不应该知道与之交互的View。

  • View

View层的逻辑很简单,就是观察ViewModel提供的属性,当其发生变化后,及时的更新UI。

最后,根据上面的描述,我们可以再来完善下上面MVVM的事件走向图:

使用Android架构组件开发MVVM模式的应用

其中,实线的部分是需要开发者手动编写的,虚线的部分应该是由通用的组件来实现,开发过程中无感知或很少感知。

LiveData

LiveData是Android架构组建中非常重要的一个成员。它提供一个范型来包装数据,它允许应用中的组建来观察LiveData中对象的变化。更进一步来讲,LiveData将数据的生产者与数据的消费者进行了分离。用代码来实际看一下:

生产者:

private val stringData : MutableLiveData<String>
 = MutableLiveData()

stringData.postValue("awesome data")

消费者:

stringData.observe(lifecycleOwner, Observer<String> {
    Log.i("TAG", it)
})

LiveData是只能由消费者来订阅它,而MutableLiveData是LiveData的子类,提供了postValue和setValue方法,可以让开发者提交生成出来的数据。大家可能会有疑问,上面的代码和我们平常接触的观察者模式很相似,那LiveData的优势在哪里呢?

LiveData最大的特性是它尊重Android组件的生命周期,上面消费者的代码中我们可以看到LiveData的ovserve方法除了需要传入第二个参数Observer,第一个参数lifecycleOwner也很重要。LifecycleOwner是一个接口,我们常见的 v4包中的Fragment、FragmentActivity都是这个接口的实现类。所以,因为有了lifecycleOwner,LiveData保证我们的observer仅会在lifecycleOwner的有效生命周期内进行回掉。当lifecycleOwner生命周期结束后,LiveData会自动将Ovserver进行清除,减少内存泄漏的风险。

LiveData第二个特性是变换,举个例子,当Model层返回了一个String类型的数据,而UI需要一个Int型的数据。这个转换,LiveData可以很轻松的胜任。Transformations类提供了map和switchMap两个方法进行转换,对于上面的例子,我们可以这样做:

//原始数据
private val stringData : MutableLiveData<String> = MutableLiveData()

//转换后的数据
val intData : LiveData<Int> = Transformations.map(stringData, {
        it?.toInt()?:0
})

通过上面的变换,Model层可以继续生产String类型的数据,而UI层也可以使用intData来观察Int类型的数据。

ViewModel

ViewModel是Android 架构组件中的另一员大将,它的生命周期依赖于对应的Activity或Fragment的生命周期。通常我们会在Activity/Fragment第一次onCreate()时创建ViewModel:

val myViewModel = ViewModelProviders.of(fragment).get(MytViewModel::class.java)

试想这样一个场景,当我们的手机屏幕发生旋转,或者系统语言发生变更后,我们的页面会被重新创建,同样的,我们的数据会因为UI的重建而再次被重新加载。但ViewModel可以保证,当屏幕旋转等配置变化后,UI组件重建后获取到的ViewModel仍是销毁之前的ViewModel,我们可以立即使用之前保留的数据。

ViewModel的生命周期一直持续到Activity最终销毁或Frament最终detached,期间由于屏幕旋转等配置变化引起的Activity销毁重建并不会导致ViewModel重建。下面是官方的ViewModel生命周期示意图:

使用Android架构组件开发MVVM模式的应用

我们可以总结一下ViewModel这样做带来的好处:

onSaveInstanceState

Paging library

分页加载的需求在应用开发的过程中很常见,Paging Library(分页组件)就是一个这样方便的组件,当列表上滑、下拉的时候可以帮助我们逐步从数据源加载信息。

分页组件中两个主要的概念是DataSource 与PageList。DataSource 表示数据来源,用于Model层。PageList表示数据列表,用于UI层。通过 LivePagedListBuilder 可以将二者进行连接。

实战应用

最后,我们可以整合上面的几个概念,开发一个MVVM架构的Android App, 我选取了Unsplash的api,制作一个可以让用户免费浏览、下载、搜索高清图片的应用。

App 效果图

使用Android架构组件开发MVVM模式的应用

App的Github地址

https://github.com/saymagic/Begonia

实现过程

整个页面大概有七八个不同的页面,我们这里以UserListFragment页面来进行举例:

使用Android架构组件开发MVVM模式的应用

这个页面的主要逻辑是根据Unsplash的 search/users 接口来查询匹配某个关键字的所有用户。页面的时序图如下:

使用Android架构组件开发MVVM模式的应用

其中UserListFragment充当M层,仅用于UI数据的展示,UserViewModel充当VM层,负责UI数据的监听和回掉。UserDataSource与Unsplash API共同充当M层,负责数据的处理和获取。 我们编写的代码主要集中在实线部分,虚线部分都是LiveData等基础组建帮我们进行实现的。

总结

MVVM相对于最大的好处就在于更灵活的解耦。在MVP上M层还需要关心怎么处理P,但在MVVM上,M层更注重怎么生产数据,其它的业务交还给VM、V层自己去处理。但总之,没有任何一种架构是能解决所有问题的,选取一个架构的时候要从产品需求、业务逻辑、团队成员的接受度等多个角度衡量和改进。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Stylin' with CSS

Stylin' with CSS

Wyke-Smith, Charles / 2012-10 / $ 50.84

In this completely revised edition of his bestselling Stylin' with CSS, veteran designer and programmer Charles Wyke-Smith guides you through a comprehensive overview of designing Web pages with CSS, ......一起来看看 《Stylin' with CSS》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具