如何构建Android MVVM运行程序

  • 电脑网络维修
  • 2024-11-14

如何构建Android MVVM运行程序

Databinding 是一种框架,MVVM是一种形式,两者的概念是不一样的。我的了解DataBinding是一个成功数据和UI绑定的框架,只是一个成功MVVM形式的工具。ViewModel和View可以经过DataBinding来成功单向绑定和双向绑定,这套UI和数据之间的灵活监听和灵活降级的框架Google曾经帮咱们做好了。在MVVM形式中ViewModel和View是用绑定相关来成功的,所以有了DataBinding 使咱们构建Android MVVM 运行程序成为或许。

1、概述

Databinding是一种框架,MVVM是一种形式,两者的概念是不一样的。我的了解DataBinding是一个成功数据和UI绑定的框架,只是一个成功MVVM形式的工具。ViewModel和View可以经过DataBinding来成功单向绑定和双向绑定,这套UI和数据之间的灵活监听和灵活降级的框架Google曾经帮咱们做好了。在MVVM形式中ViewModel和View是用绑定相关来成功的,所以有了DataBinding使咱们构建Android MVVM 运行程序成为或许。

之前看了很多关于DataBinding的博客和相关的一些Demo,大少数就是往xml规划文件传入一些数据,然后把这些数据绑定到控件上( 如TextViewbinding:text=“@{user.name} ),接着在这些控件上(如Buttonbinding:setOnClickListener=”@{user.listener}”)设置一些事情到控件上,基本讲述都是DataBinding的基本用法。但是并没有人通知你把一个onClickListener写到一个类并把这个listener绑定到xml外面上是不是不太好,也没有人通知你这个和xml规划绑定的ViewModel类应该放哪些数据,应该做什么事?应该如何设计?更是很少有博文来通知你在Android中如何经过Data Binding 去构建MVVM的运行框架。这也就是是本篇文章的重点。接上去,咱们先来看看什么是MVVM,然后在一步一步来设计整个运行程序框架。

源码地址

2、MVC、MVP、MVVM

首先,咱们先大抵了解Android开发中经常出现的形式,以便咱们更深化了解MVVM 形式。

View:对应于xml规划文件

Model:实体模型

Controllor:对应于Activity业务逻辑,数据处置和UI处置

从上方看起来各个组件的职责视乎还挺耦合MVC的,但是关上Android的一个Activity文件,一看一言难尽,Android中经常会产生数千行的Activity代码,究其要素,Android中纯正作为View的各个XML视图配置太弱,Activity基本上都是View和Controller的合体,既要担任视图的显示又要参与控制逻辑,承当的配置过多,代码量大也就无余为奇。一切更贴切的目前惯例的开发说应该是View-Model形式,大局部都是经过Activity的协调,衔接,和处置逻辑的。

View: 对应于Activity和xml,担任View的绘制以及与用户交互

Model: 依然是实体模型

Presenter: 担任成功View于Model间的交互和业务逻辑

在Android开发中MVP的设计思维用得比拟多,应用MVP的设计模型可以把局部的逻辑的代码从Fragment和Activity业务的逻辑移进去,在Presenter中持有View(Activity或许Fragment)的援用,然后在Presenter调用View暴露的接口对视图启动操作,这样无利于把视图操作和业务逻辑分开来。MVP能够让Activity成为真正的View而不是View和Control的合体,Activity只做UI相关的事。但是这个形式还是存在一些不好的中央,比拟如说:

复杂的业务同时会造成presenter层太大,代码臃肿的疑问。

View: 对应于Activity和xml,担任View的绘制以及与用户交互

Model: 实体模型

ViewModel: 担任成功View于Model间的交互,担任业务逻辑

MVVM的指标和思维MVP相似,应用数据绑定(Data Binding)、依赖属性(DependencyProperty)、命令(Command)、路由事情(Routed Event)等新个性,打造了一个愈加灵敏高效的架构。

在MVVM中,以前开发形式中必定先处置业务数据,然后依据的数据变动,去失掉UI的援用然后降级UI,经过也是经过UI来失掉用户输入,而在MVVM中,数据和业务逻辑处于一个独立的ViewModel中,ViewModel只需关注数据和业务逻辑,不须要和UI或许控件打交道。由数据智能去驱动UI去智能降级UI,UI的扭转又同时智能反应到数据,数据成为主导要素,这样使得在业务逻辑处置只需关心数据,繁难而且繁难很多。

MVVM形式中,数据是独立于UI的,ViewModel只担任处置和提供数据,UI想怎样处置数据都由UI自己选择,ViewModel不触及任何和UI相关的事也不持有UI控件的援用,即使控件扭转(TextView 换成 EditText)ViewModel简直不须要更改任何代码,专一自己的数据处置就可以了,假设是MVP遇到UI更改,就或许须要扭转失掉UI的形式,扭转降级UI的接口,扭转从UI上失掉输入的代码,或许还须要更改访问UI对象的属性代码等等。

在MVVM中,咱们可以在上班线程中间接修正ViewModel的数据(只需数据是线程安保的),剩下的数据绑定框架帮你搞定,很多事情都不须要你去关心。

MVVM的分工是十分显著的,由于View和ViewModel之间是松懈耦合的。一个是处置业务和数据,一个是专门的UI处置。齐全有两团体分工来做,一个做UI(xml 和Activity)一个写ViewModel,效率更高。

一个ViewModel复用到多个View中,雷同的一份数据,用不同的UI去做展现,关于版本迭代频繁的UI改动,只需改换View层就行,关于假构想在UI上的做AbTest更是繁难的多。

ViewModel外面是数据和业务逻辑,View中关注的是UI,这样的做测试是很繁难的,齐全没有彼此的依赖,不论是UI的单元测试还是业务逻辑的单元测试,都是低耦合的。

经过上方对MVVM的简述和其余两种形式的对比,咱们发现MVVM对比MVC和MVP来说还是存在比拟大的长处,只管目前Android开发中或许真正在经常使用MVVM的很少,但是是值得咱们去做一些讨论和调研。

3、如何构建MVVM运行程序

1). 如何分工

构建MVVM框架首先要详细了解各个模块的分工,接上去咱们来解说View,ViewModel,Model 的它们各自的职责所在。

View层做的就是和UI相关的上班,咱们只在XML和Activity或Fragment写View层的代码,View层不做和业务相关的事,也就是咱们的Activity不写和业务逻辑相关代码,也不写须要依据业务逻辑来降级UI的代码,由于降级UI经过Binding成功,降级UI在ViewModel外面做(降级绑定的数据源即可),Activity要做的事就是初始化一些控件(如控件的色彩,参与 RecyclerView的宰割线),Activity可以降级UI,但是降级的UI必定和业务逻辑和数据是没有相关的,只是单纯的依据点击或许滑动等事情降级UI(如依据滑动色彩突变、依据点击暗藏等单纯UI逻辑),Activity(View层)是可以处置UI事情,但是处置的只是处置UI自己的事情,View层只处置View层的事。繁难的说:View层不做任何业务逻辑、不触及操作数据、不处置数据、UI和数据严厉的分开。

ViewModel层做的事情刚好和View层雷同,ViewModel 只做和业务逻辑和业务数据相关的事,不做任何和UI、控件相关的事,ViewModel层不会持有任何控件的援用,更不会在ViewModel中经过UI控件的援用去做降级UI的事情。ViewModel就是专一于业务的逻辑处置,操作的也都是对数据启动操作,这些个数据源绑定在相应的控件上会智能去更改UI,开发者不须要关心降级UI的事情。DataBinding框架曾经允许双向绑定,这使得咱们在可以经过双向绑定失掉View层反应给ViewModel层的数据,并启动操作。关于对UI控件事情的处置,咱们也宿愿能把这些事情处置绑定到控件上,并把这些事情一致化,繁难ViewModel对事情的处置和代码的好看。为此咱们经过BindingAdapter对一些罕用的事情做了封装,把一个个事情封装成一个个Command,关于每个事情咱们用一个ReplyCommand<T>去处置就行了,ReplyCommand<T>会把或许你须要的数据带给你,这使得咱们处置事情的时刻也只关心处置数据就行了,详细见MVVMLight Toolkit 经常使用指南的 Command 局部。再强调一遍ViewModel 不做和UI相关的事。

Model 的职责很繁难,基本就是实体模型(Bean)同时包括Retrofit 的Service ,ViewModel 可以依据Model失掉一个Bean的Observable<Bean>( RxJava ),然后做一些数据转换操作和映射到ViewModel中的一些字段,最后把这些字段绑定到View层上。

2). 如何单干

关于单干,咱们先来看上方的一张图:

图 1

上图反响了MVVM框架中各个模块的咨询和数据流的走向,由上图可知View和Model 间接是解耦的,是没有间接咨询的,也就是我之前说到的View不做任何和业务逻辑和数据处置相关的事。咱们从每个模块逐一拆分来看。那么咱们重点就是上方的三个单干。

ViewModel与View的单干

图 2

图 2 中ViewModel 和View 是经过绑定的形式衔接在一同的,绑定的一种是数据绑定,一种是命令绑定。数据的绑定>

//一个变量蕴含了一切关于/***ViewStyle关于控件的一些属性和业务数据有关的Style可以做一个包裹,这样代码比拟好看,ViewModel页面也不会有太多的字段。**/

Context 是干嘛用的呢,为什么每个ViewModel都最好须要持了一个Context的援用呢?ViewModel不做和UI相关的事,不操作控件,也不降级UI,那为什么要有Context呢?要素关键有以下两点,当然也有其余用途,调用工具类、协助类或许须要context参数等:

经过图1中,咱们发现ViewModel 经过传参给Model然后失掉一个Observable<Bean>,其实这就是网络恳求局部,做网络恳求咱们必定把RetrofitService前往的Observable<Bean>绑定到Context的生命周期上,防止在恳求回来时Activity曾经销毁等意外,其实这个Context的目的就是把网络恳求绑定到页面的生命周期中。

在图1中,咱们可以看到两个ViewModel 之间的咨询是经过Messenger来做,这个Messenger是须要用到Context,这个咱们后续会解说。

Model 是什么呢,其实就是数据原型,也就是咱们用Json转上来的JavaBean,咱们或许都知道,ViewModel要把数据映射到View中或许须要少量对Model的数据拷贝,拿Model的字段去生成对应的ObservableField(咱们不会间接拿Model的数据去做展现),这里其实是有必要在一个ViewModel保管原始的Model援用,这关于咱们是十分有用的,由于或许用户的某些操作和输入须要咱们去扭转数据源,或许咱们须要把一个Bean从列表页点击后传给概略页,或许咱们须要把这个model 当做表单提交到主机。这些都须要咱们的ViewModel 持有相应的model。

Data Field (数据绑定)

Data Field 就是须要绑定到控件上的ObservableField字段,无可非议这是ViewModel的必定品。这个没有什么好说,但是这边有一个倡导:

这些字段是可以稍微做一下分类和包裹的,比如说或许一些字段绑定到控件的一些Style属性上(假设说:长度,色彩,大小)这些依据业务逻辑的变动而灵活去更改的,关于着一类针对ViewStyle的的字段可以申明一个ViewStyle类包裹起来,这样整个代码逻辑会更明晰一些,不然ViewModel外面或许字段众多,不易治理和浏览性较差。而关于其余一些字段,比如说title,imageUrl,name这些属于数据源类型的字段,这些字段也叫数据字段,是和业务逻辑毫不相关的,这些字段可以放在一块。

Command (命令绑定)

Command(命令绑定)说白了就是对事情的处置(下拉刷新,加载更多,点击,滑动等事情处置),咱们之前处置事情是拿到UI控件的援用,然后设置Listener,这些Listener其实就是Command,但是思考到在一个ViewModel 写各种Listener并不好看,或许成功一个Listener就须要成功多个方法,但是咱们或许只想要其中一个有用的方法成功就好了。同时成功Listener会拿到UI的援用,或许会去做一些和UI相关的事情,这和咱们之前说的ViewModel 不持有控件的援用,ViewModel不更改UI有相悖。更关键一点是成功一个Listener或许须要写一些UI逻辑能力最终失掉咱们想要的,繁难一点的比如说,你想要监听ListView滑到最底部然后触发加载更多的事情,这时刻你就要在ViewModel外面写一个OnScrollListener,然后在外面的onScroll方法中做计算,计算什么时刻ListView滑动底部了,其实ViewModel的上班并不想去处置这些事情,它专一做的应该是业务逻辑和数据处置,假设有一个物品它不须要你自己去计算能否滑究竟部,而是在滑动底部智能触发一个Command,同时把列表的总共的item数量前往给你,繁难你经过page=itemCount/LIMIT+1去计算出应该恳求主机哪一页的数据那该多好啊。MVVM Light Toolkit 帮你成功了这一点:

接着在XML 规划文件中经过bind:onLoadMoreCommand绑定上去就行了

详细想了解更多请检查 MVVM Light Toolkit经常使用指南,外面有比拟详细的解说Command的经常使用。当然Command并不是必定的,你齐全可以依照你的习气和喜好在ViewModel写Listener,不过经常使用Command 可以使你的ViewModel更繁复易读,你也可以自己定义更多的Command,自己定义其余配置Command,那么ViewModel的事情处置都是托管ReplyCommand<T>来处置,这样的代码看起来会特意好看和明晰。

Child ViewModel (子ViewModel)

子ViewModel 的概念就是在ViewModel外面嵌套其余的ViewModel,这种场景还是很经常出现的。比如说你一个Activity外面有两个Fragment,ViewModel是以业务划分的,两个Fragment做的业务不一样,人造是由两个ViewModel来处置,Activity 自身或许就有个ViewModel来做它自己的业务,这时刻Activity的这个ViewModel外面或许蕴含了两个Fragment区分的ViewModel。这就是嵌套的子ViewModel。还有另外一种就是关于AdapterView如ListView RecyclerView,ViewPager等。

它们的每个Item 其实就对应于一个ViewModel,然后在的ViewModel经过ObservableList<ItemViewModel>持有援用(如上述代码),这也是很经常出现的嵌套的子ViewModel。咱们其实还倡导,假设一个页面业务十分复杂,不要把一切逻辑都写在一个ViewModel,可以把页面做业务划分,把不同的业务放到不同的ViewModel,然后整合到一个总的ViewModel,这样做起来可以使咱们的代码业务明晰,冗长意赅,也繁难前人的保养。

总得来说ViewModel 和View之前仅仅只要绑定的相关,View层须要的属性和事情处置都是在xml外面绑定好了,ViewModel层不会去操作UI,只会操作数据,ViewModel只是依据业务要求处置数据,这些数据智能映射到View层控件的属性上。关于ViewModel类中蕴含哪些模块和字段,这个须要开发者自己去权衡,这边倡导ViewModel不要引入太多的成员变量,成员变量最好只要上方的提到的5种(context、model、…),能不进入其余类型的变量就尽量不要引出去,太多的成员变量关于整个代码结构破坏很大,前面保养的人要时辰关心成员变量什么时刻被初始化,什么时刻被清掉,什么时刻被赋值或许扭转,一个细节不小心或许就产生潜在的Bug。太多不明晰定义的成员变量又没有注释的代码是很难保养的。

ViewModel与Model的单干

从图1 中,Model 是经过Retrofit 去失掉网络数据的,前往的数据是一个Observable<Bean>( RxJava),Model 层其实做的就是这些。那么ViewModel做的就是经过传参数到Model层失掉到网络数据(数据库同理)然后把Model的局部数据映射到ViewModel的一些字段(ObservableField),并在ViewModel保管这个Model的援用,咱们来看下这一块的大抵代码(代码触及到繁难RxJava,如看疑问可以查阅入门一下):

//将网络恳求绑定到Activity的生命周期//变成Notification<Bean>使咱们更繁难处置数据和失误//给成员变量newsDetail赋值,之前提到的5种变量类型中的一种(model类型)//Model

以上代码基本把注释补全了,基本思绪比拟明晰,,Rxjava触及的操作符都是比拟基本的,如有疑问,可以稍微去入门,之后的源码外面ViewModel数据逻辑处置都是用Rxjava做,所以须要提早学习一下繁难你看懂源码。

注:咱们介绍经常使用MVVM 和RxJava一块经常使用,只管两者皆有观察者形式的概念,但是咱们RxJava不经常使用在针对View的监听,更多是业务数据流的转换和处置。DataBinding框架其实是公用于View-ViewModel的灵活绑定的,它使得咱们的ViewModel只须要关注数据,而RxJava提供的弱小数据流转换函数刚好可以用来处置ViewModel中的种种数据,失掉很好的用武之地,同时加上Lambda表白式联合的链式编程,使ViewModel的代码十分繁复同时易读易懂。

ViewModel与ViewModel的单干

在图 1 中 咱们看到两个ViewModel 之间用一条虚线衔接着,两边写着Messenger,Messenger可以了解是一个全局信息通道,引入messenger最关键的目的就成功ViewModel和ViewModel的通讯,也可以用做View和ViewModel的通讯,但是并不介绍这样做。ViewModel关键是用来处置业务和数据的,每个ViewModel都有相应的业务职责,但是在业务复杂的状况下,或许存在交叉业务,这时刻就须要ViewModel和ViewModel交流数据和通讯,这时刻一个全局的信息通道就很关键的。关于Messenger的详细经常使用方法可以参照 MVVM Light Toolkit 经常使用指南的 Messenger 局部,这边给出一个繁难的例子仅供参考:

场景是这样的,你的MainActivity对应一个MainViewModel,MainActivity外面除了自己的内容还蕴含一个Fragment,这个Fragment的业务处置对应于一个FragmentViewModel,FragmentViewModel恳求主机并失掉数据,刚好这个数据MainViewModel也须要用到,咱们无法能在MainViewModel从新恳求数据,这样不太正当,这时刻就须要把数据传给MainViewModel,那么应该怎样传,彼此没有援用或许回调。那么只能经过全局的信息通道Messenger。FragmentViewModel失掉信息后通知MainViewModel 并把数据传给它:

//上方的代码可以不看,就是失掉网络数据,经过send把数据传过去

在MainActivity onDestroy 敞开注册就行了(不然造成内存暴露)

当然上方的例子也只是繁难的说明下,Messenger可以用在很多场景,通知,广播都可以,不必定要传数据,在必定条件下也可以用在View层和ViewModel上的通讯和广播。运用范围特意广,须要开发者联合实践的业务中去做更深档次的开掘。

4、总结和源码

本篇博文解说关键是一些团体开发环节中总结的Android MVVM构建思维,更多是通常上各个模块如何分工,代码如何设计,只管如今业界经常使用AndroidMVVM形式开发还比拟少,但是随着DataBinding 1.0 的发布,置信在Android MVVM这块畛域会更多的人来尝试,刚好最近用MVVM开发了一段期间,有点心得,写进去仅供参考。

文中解说的环节代码比拟少,代码用到了自己开发的一个MVVM Light Toolkit 库,而且还是RxJava + Lambda的代码,预计很多人看着都晕菜了,这边会把源码发布进去。假设你还没有尝试过用RxJava+Retrofit+DataBinding 构建Android MVVM运行程序,那么你可以试着看一下这边的源码并且做一下尝试,说不定你会青睐上这样的开发框架。

关于MVVM Light Toolkit 只是一个工具库,关键目的是更快捷繁难的构建AndroidMVVM运行程序,在外面参与了一些控件额外属性和做了一些事情的封装,同时引进了全局信息通道Messenger,用起来确实十分繁难,你可以尝试一下,当然还有不少中央没有完善和提升,后续也会始终降级和提升,假设不能到达你的业务需求时,你也可以自己参与自己须要的属性和事情。假构想更深化了解MVVMLight Toolkit 请看我这篇博文 MVVM Light Toolkit 经常使用指南

源码地址

library —> library是MVVM Light Toolkit的源码,源码很繁难,感兴味的同窗可以看看,没什么多少的技术难度,可以依据自己的需求,参与更多的控件的属性和事情绑定。

sample —> 本文触及的代码均处出于这个名目,sample 一个知乎日报的App的繁难成功,代码蕴含了一大局部 MVVM LightToolkit的经常使用场景,(Data、Command、Messenger均有触及),同时sample严厉依照博文论述的MVVM的设计思维开发的,对了解本文有很大的协助,欢迎clone上去看看。

Sample 截图

源码触及 RxJava+Retrofit+Lambda 如有疑问或没接触过,花点期间入门一下,用到都是比拟繁难的物品。宿愿这篇博客在如何构建AndroidMVVM运行程序对你有所协助,如有任何疑问,可以给我留言,欢迎大家独特讨论,假设对MVVM Light Toolkit 有任何疑问,也可以反应给我。

  • 关注微信

本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载联系作者并注明出处:https://duobeib.com/diannaowangluoweixiu/4911.html

猜你喜欢

热门标签

洗手盆如何疏浚梗塞 洗手盆为何梗塞 iPhone提价霸占4G市场等于原价8折 明码箱怎样设置明码锁 苏泊尔电饭锅保修多久 长城画龙G8253YN彩电输入指令画面变暗疑问检修 彩星彩电解除童锁方法大全 三星笔记本培修点上海 液晶显示器花屏培修视频 燃气热水器不热水要素 热水器不上班经常出现3种处置方法 无氟空调跟有氟空调有什么区别 norltz燃气热水器售后电话 大连站和大连北站哪个离周水子机场近 热水器显示屏亮显示温度不加热 铁猫牌保险箱高效开锁技巧 科技助力安保无忧 创维8R80 汽修 a1265和c3182是什么管 为什么电热水器不能即热 标致空调为什么不冷 神舟培修笔记本培修 dell1420内存更新 青岛自来水公司培修热线电话 包头美的洗衣机全国各市售后服务预定热线号码2024年修缮点降级 创维42k08rd更新 空调为什么运转异响 热水器为何会漏水 该如何处置 什么是可以自己处置的 重庆华帝售后电话 波轮洗衣机荡涤价格 鼎新热水器 留意了!不是水平疑问! 马桶产生了这5个现象 方便 极速 邢台空调移机电话上门服务 扬子空调缺点代码e4是什么疑问 宏基4736zG可以装置W11吗 奥克斯空调培修官方 为什么突然空调滴水很多 乐视s40air刷机包 未联络视的提高方向 官网培修 格力空调售后电话 皇明太阳能电话 看尚X55液晶电视进入工厂形式和软件更新方法 燃气热水器缺点代码

热门资讯

关注我们

微信公众号