写点什么

Android 三类框架的理解以及 MVVM 框架的使用

用户头像
Android架构
关注
发布于: 2021 年 11 月 07 日
  1. 目前使用的最多的是 MVC MVP

  2. 其中 MVC 出现与上世纪 70 年代,在三十多年的工程实践中,MVC 充分证明了它的成功,同时在漫长的时间中演变出了许多变种,其中也包括 MVP。MVC MVP 最大的差别在与控制层对于整个框架的控制力上。

  3. MVVM 可以算是 MVP 的升级版,其中的 VM 是 ViewModel 的缩写,ViewModel 可以理解成是 View 的数据模型和 Presenter 的合体,ViewModel 和 View 之间的交互通过 Data Binding 完成,而 Data Binding 可以实现双向的交互,这就使得视图和控制层之间的耦合程度进一步降低,关注点分离更为彻底,同时减轻了 Activity 的压力

  4. 三者之间的差别如下:



**甘特图


Mon 07 Mon 14 1.MVP 2.MVC 3.MVVM 进步图 安卓各类框架进步


**流程图


被替代


MVP


MVC


MCV


MVVM


二、Android 开发中 MVC 与 MVP 的区别




话不多说,直接上图


1.MVC 架构图



2.MVP 架构图



三个架构


| 架构类型 | 构造子 |


| --- | --- |


| MVP | Model, Presenter, View |


| MVC | Model, Controller ,View |


| MVVM | Model, View ,ViewModel |


3.简要分析区别


  1. Activity 职责不同,Activity 在 MVP 中是 View 层,在 MVC 中是 Controller 层,这是 MVC 和 MVP 很主要的一个区别,可以说 Android 从 MVC 转向 MVP 开发也主要是优化 Activity 的代码,避免 Activity 的代码臃肿庞大。

  2. View 层不同,MVC 的 View 层指的是 XML 布局文件或者是用 Java 自定义的 View,MVP 的 View 层是 Activity 或者 Fragment。使用传统的 MVC,其中的 View,对应的是各种 Layout 布局文件,但是这些布局文件中并不像 Web 端那样强大,能做的事情非常有限。MVP 的 View 层 Activity 在实际项目中,随着逻辑的复杂度越来越大,Activity 臃肿的缺点仍然体现出来了,因为 Activity 中还是充满了大量与 View 层无关的代码,比如各种事件的处理派发,就如 MVC 中的那样 View 层和 Controller 代码耦合在一起无法自拔。

  3. 控制层不同,MVC 的控制层是 Activity,或者是 Fragment,Controller 对应的是 Activity,而 Activity 中却又具有操作 UI 的功能,我们在实际的项目中也会有很多 UI 操作在这一层,也做了很多 View 中应该做的事情,当然 Controller 层 Activity 中也包含 Controller 应该做的事情,比如各种事件的派发回调,而且在一层中我们会根据事件再去调用 Model 层操作数据,所以这种 MVC 的方式在实际项目中,Activity 所在的 Controller 是非常重的,各层次之间的耦合情况也比较严重,不方便单元测试。MVP 的控制层是 Presenter,里面没有很多的实际东西,主要是做 Model 和 View 层的交互。

  4. 关系链不同,MVP 中 Model 层与 View 是没有关系的,彼此不会通讯和操作,Model 与 View 的通讯都是 Presenter 层来传达的。但是在 MVC 中,Model 层和 View 是曾在交互的。比如我们自定义的 View 控件里面肯定是要使用 Model 的数据的,View 也要根据不同的 Model 数据做出不同的展现!这点尤其是体现在自定义的 View 中,自定义 View 需要设置数据,用户操作了自定义控件需要改变数据,View 要操作 Model 怎么办?有人说把 Controller 传到自定义的 View 啊,现实是不可能没一个自定义 View 都去持有 Controller 的引用,其实在 MVP 中就不会这么尴尬,接口就可以完成。

  5. 适用范围不同,在 Android 中,MVP 和 MVC 都用自己的适用情况,使用 MVP 可以更好的解耦三大模块,模块之间比较清晰,也很方便使用 MVP 来组件化架构整体项目。但是 MVC 也是有用武之地的,在组件化的 Module 或者中间件我们可以使用 MVC 来做,Module 或者中间件不会存在很复杂的 View 层,使用 MVC 可以更加方便我们实现功能。


6.** 交互方式不同**,MVP 中通讯交互基本都是通过接口的,MVC 中的通讯交互很多时候都是实打实的调用对象的方法,简单粗暴!


  1. **实现方法不同 **,MVC 和 MVP 的 Model 几乎一样的,都是处理数据,只要不在 Activity 或者 Fragment 中请求数据,其他的所有控制都放在 Activity 或者 Fragment 中,这样写就基本是 MVC 的模式,这样写不麻烦,但是很容易把 Activity 写出上万行代码。用 MVP 的时候我们需要写很多 View 和 Presenter 接口来实现模块之间的通讯,会增加很多类。


三、MVVM 架构优势(单独讲)




话不多说,直接上图



看上图 Model 和 View 是不会发生关系的,ViewModel 是把 View 和 Model 关联起来的加工厂:



MVVM 优势总结:


  • ViewModel双向绑定,一方的改变都会影响另一方,开发者不用再去手动修改 UI 的数据。额,互相自动的。

  • 不需要findViewById也不需要butterknife,不需要拿到具体的 View 去设置数据绑定监听器等等,这些都可以用DataBinding完成。是不是很舒服?

  • ViewModel的双向绑定是支持生命周期检测的,不会担心页面销毁了还有回调发生,这个由lifeCycle完成。

  • 不会像MVC一样导致Activity中代码量巨大,也不会像MVP一样出现大量的ViewPresenter接口。项目结构更加低耦合。

  • 更低的耦合把各个模块分开开发,分开测试,可以分给不同的开发人员来完成。


四、深入学习 MVVM 组件化




示例项目架构分析


1.MVVM 组件化示例项目架构图



2.目录结构:



各模块和彼此之间的关系解释


  • lib_opensource:第三方build.gradle依赖,本项目主要有support、lifecycle、room、fresco、retrofit、okhttp、RxJava、ARouter这些。


-lib_coremodel: 存放MVVM中的ModelViewModel两个模块,就是数据的处理和数据与 UI 页面的绑定。依赖lib_opensource库。


-lib_common: 公共库,主要有各种 base,各种 ui 组件,自定义组件,公用的Activity、公用的Fragment,和公用的utils等等。依赖lib_coremodel库。


  • module_girls: 子功能模块,可以在libraryapplication之间切换,自己可以是一个 app 也可以成为别的 app 的一个组件模块。组件化编译时为 app,反之为module

  • module_news: 新闻功能模块,可以在libraryapplication之间切换,自己可以是一个 app 也可以成为别的 app 的一个组件模块。组件化编译时为app,反之为module

  • app_universal: 定制版本的 app,组件化编译时module_girlsmodule_news为 app,所以不能把这两个作为 module 加进来编译,所以组件化编译时app_universal要依赖lib_common库,反之就可以把 module_girlsmodule_news作为 module 加进来编译。

  • app_specific: 定制版本的app,组件化编译时module_girlsmodule_news为 app,所以不能把这两个作为 module 加进来编译,所以组件化编译时app_specific要依赖lib_common库,反之就可以把 module_girlsmodule_news作为module加进来编译


五:android MVVM 框架实现 Robobinding




  • Android 平台上有一些比较好的 MVVM 框架,其中用的比较多的是 RoboBinding,Robobinding。

  • 为了精简框架,RoboBinding 移除了大量不必要的代码,比如 addXXListener(),findViewById()等。

  • 可以将难以测试的 Android 代码转换为普通的 JUnit 测试。

  • 提供对象类型 Cursor 来替换 - 关系类型 Cursor,因为我们已经习惯于操作对象 。

  • 可以很容易的为任何自定义组件,第三方组件或 Android widget 编写属性绑定实现,简化代码,使项目易于维护


-----------------------------------------Robobiding 简单使用示例:----------------------------------------------


  • View 层(对应 android xml 文件)


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"


xmlns:bind="http://robobinding.org/android"


xmlns:tools="http://schemas.android.com/tools"


android:layout_width="match_parent"


android:layout_height="match_parent"


android:orientation="vertical"


tools:context="org.robobinding.androidmvvm.MainActivity"


tools:ignore="MissingPrefix">


<TextView


android:layout_width="wrap_content"


android:layout_height="wrap_content"


bind:text="{hello}"/> //单向绑定,修改 Model 属性时,会自动反映到视图中(需要实体中提供相应的 getHello(),setHello()方法)。


<LinearLayout


android:layout_width="match_parent"


android:layout_height="wrap_content"


android:orientation="horizontal">


<TextView


android:layout_width="wrap_content"


android:layout_height="wrap_content"


android:text="Name:"/>


<EditText


android:layout_width="fill_parent"


android:layout_height="wrap_content"


bind:text="${name}"/> //双向绑定,修改 model 属性时,会自动反映到视图中;反过来,修改视图内容,也会自动更改 Model 的相关属性。


</LinearLayout>


<Button


android:layout_width="wrap_content"


android:layout_height="wrap_content"


android:text="Say Hello"


bind:onClick="sayHello"/>


</LinearLayout>


  • Model 层:PresentationModel()


public class PresentationModel implements HasPresentationModelChangeSupport {


private PresentationModelChangeSupport changeSupport;


private String name;


public PresentationModel() {


changeSupport = new PresentationModelChangeSupport(this);


}


public String getHello() {


return name + ": hello Android MVVM(Presentation Model)!";


}


public String getName() {


return name;


}


public void setName(String name) {


this.name = name; Log.d("model", "setName(),name: " + name);


}


public void sayHello(){


changeSupport.firePropertyChange("hello");


}


@Override


public PresentationModelChangeSupport getPresentationModelChangeSupport() {


return changeSupport;


}


}


**Controller 层: **


public class MainActivity extends Activity {


@Override


protected void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);


PresentationModel presentationModel = new PresentationModel();


ViewBinder viewBinder = createViewBinder();


View rootView = viewBinder.inflateAndBind(R.layout.activity_main, presentationModel);//将 model 和 view 进行绑定


setContentView(rootView);


}


private ViewBinder createViewBinder() {


BinderFactory reusableBinderFactory = new BinderFactoryBuilder().build();


return reusableBinderFactory.createViewBinder(this);


}


}


**---------------------


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


-------------------------Robobiding 简单使用结束:------------------------------------------------**


六、android 官方 databinding 使用




android 官方支持的 databinding 框架使用


使用条件:


  • android studio 1.3 及以上版本

  • gradle 2.2 及以上版本

  • android plugin for gradle 1.3.0 及以上版本


使用步骤:


  1. 在项目顶层 build.gradle 中添加以下依赖:


dependencies { classpath "com.android.databinding:dataBinder:1.0-rc1"}


  1. 在需要使用 databinding 的 moudle 中添加


apply plugin: 'com.android.databinding'


注意


在项目编译过程中,会出现诸如以下错误:


错误一:


Error:Application and test application id cannot be the same: both are 'com.fengjr.mobile' for qihuDebugAndroidTest


此处要求 test 的 application id 和项目 id 不能一致,需将 test 的 id(即 testApplicationId “com.fengjr.mobile"修改为"com.fengjr.mobile.test”)


示例

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android 三类框架的理解以及MVVM框架的使用