Android之MVVM开发模式
MVVM 模式简介
MVVM模式是指Model-View-ViewModel。相信看过笔者关于MVP的文章的读者也会发现,无论如何抽象化,在我们的View层中是无法避免的要处理一部分逻辑的。而MVVM模式中的View是将View的状态和行为完全抽象化,把逻辑与界面的控制完全交给ViewModel处理。
MVVM由下面三个核心组件组成:
- Model: 用于获取业务数据模型
- View: 定义了界面中的布局和外观
- ViewModel: 逻辑控制层,负责处理数据和处理View层中的业务逻辑
什么是DataBinding
DataBinding是Google官方推出的数据绑定器,这个绑定器的作用是把数据和View绑定起来,然后数据改变的时候View会自动刷新,这个DataBinding就是我们实现MVVM模式的关键。
引入DataBinding
引入DataBinding的方式很简单,我们只需要在Module的build.gradle添加如下代码即可。
android{
....
dataBinding{
enabled true
}
}
使用DataBinding
使用DataBinding的布局文件和普通的布局文件有点不同,DataBinding布局文件的根标签是layout标签,layout里面有一个data元素和View元素,这个View元素就是我们没使用DataBinding时候的布局文件。下面看看例子代码:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
tools:context="com.loaderman.modedemo.MainActivity"> <data> <variable
name="user"
type="com.loaderman.modedemo.User" /> <variable
name="myHandlers"
type="com.loaderman.modedemo.myHandlers" />
</data> <LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"> <TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:onClick="@{myHandlers.onClickName}"
android:text="@{user.name}" />
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:text="更新数据"
android:layout_height="wrap_content" /> </LinearLayout> </layout>
Android MVVM 模式
MVVM在不同的平台实现方式是有一定差异性的。在Google IO 2017 ,Google发布了一个官方应用架构库Architecture Components,这个架构库便是Google对Android应用架构的建议,也被称之为Android官方应用架构指南。Android Architecture Components在Google中国开发者网站中能找到。和Data Binding Library一样官方还没翻译为中文。
下图是Architecture的应用架构图。结合Android程序特点,整体上与微软的MVVM类似,但是做了更细致的模块划分。
View
显而易见 Activity/Fragment 便是MVVM中的View,当收到ViewModel传递来的数据时,Activity/Fragment负责将数据以你喜欢的方式显示出来。实际是View成还包括ViewDataBinding(根据xml自动生成),上面中并没有体现。
ViewModel
ViewModel作为Activity/Fragment与其他组件的连接器。负责转换和聚合Model中返回的数据,使这些数据易于显示,并把这些数据改变及时的通知给Activity/Fragment。
ViewModel是具有生命周期意识的,当Activity/Fragment销毁时ViewModel的onClear方法会被回调,你可以在这里做一些清理工作。
LiveData是具有生命周期意识的一个可观察的的数据持有者,ViewModel中的数据由LiveData持有,并且只有当Activity/Fragment处于活动时才会通知UI数据的改变,避免无用的刷新UI;
Model
Repository及其下方就是Model了。Repository负责提取和处理数据。数据可以来自本地数据库(Room),也可以来自网络,这些数据统一有Repository处理,对应隐藏数据来源及获取方式
Binder 绑定器
上图中并没有标出绑定器在哪里,其实在任何MVVM的实现中,数据绑定技术都是必须的。而上图仅仅是应用架构图。
Android中的数据绑定技术由 DataBinding和LiveData共同实现。当Activity/Fragment接收到来自ViewModel中的新数据时(由LiveData自动通知数据的改变),将这些数据通过DataBinding绑定到ViewDataBinding中,UI将会自动刷新,而不用书写类似setText的方法。
数据对象
package com.loaderman.modedemo; public class User {
public String name; }
事件绑定对象
package com.loaderman.modedemo; import android.view.View;
import android.widget.TextView;
import android.widget.Toast; public class myHandlers {
public void onClickName(View view){
TextView view1 = (TextView) view;
Toast.makeText(view.getContext(),view1.getText().toString(),Toast.LENGTH_SHORT).show();
}
}
MainActivty.java
package com.loaderman.modedemo; import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View; import com.loaderman.modedemo.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity {
User user;
private ActivityMainBinding dataBinding; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
user = new User();
dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//模拟数据更新
user.name = "android ";
dataBinding.setUser(user);
}
});
user.name = "loaderman";
//数据绑定
dataBinding.setUser(user);
//事件绑定
dataBinding.setMyHandlers(new myHandlers());
} }
在listview 等列表的adapter中使用数据绑定,可以使用如下方式
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
DataBindingUtil.inflate(inflater,R.layout.activity_main, viewgroup,false);
MVVM设计模式的优点
1.双向绑定技术,当Model变化时,View-Model会自动更新,View也会自动变化。很好做到数据的一致性,不用担心,在模块的这一块数据是这个值,在另一块就是另一个值了。所以 MVVM模式有些时候又被称作:model-view-binder模式。
2.View的功能进一步的强化,具有控制的部分功能,若想无限增强它的功能,甚至控制器的全部功几乎都可以迁移到各个View上(不过这样不可取,那样View干了不属于它职责范围的事情)。View可以像控制器一样具有自己的View-Model.
3.由于控制器的功能大都移动到View上处理,大大的对控制器进行了瘦身。不用再为看到庞大的控制器逻辑而发愁了。
4.可以对View或ViewController的数据处理部分抽象出来一个函数处理model。这样它们专职页面布局和页面跳转,它们必然更一步的简化。
MVVM设计模式的缺点
第一点:数据绑定使得 Bug 很难被调试。你看到界面异常了,有可能是你 View 的代码有 Bug,也可能是 Model 的代码有问题。数据绑定使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。
第二点:一个大的模块中,model也会很大,虽然使用方便了也很容易保证了数据的一致性,当时长期持有,不释放内存,就造成了花费更多的内存。
第三点:数据双向绑定不利于代码重用。客户端开发最常用的重用是View,但是数据双向绑定技术,让你在一个View都绑定了一个model,不同模块的model都不同。那就不能简单重用View了。
Android之MVVM开发模式的更多相关文章
- 玩转Android之MVVM开发模式实战,炫酷的DataBinding!
C# 很早就有了MVVM的开发模式,Android手机中的MVVM一直到去年Google的I\O大会上才推出,姗姗来迟.MVVM这中开发模式的优点自不必多说,可以实现视图和逻辑代码的解耦,而且,按照G ...
- js架构设计模式——理解javascript中的MVVM开发模式
理解javascript中的MVVM开发模式 http://blog.csdn.net/slalx/article/details/7856769 MVVM的全称是Model View ViewMod ...
- MVVM开发模式简单实例MVVM Demo
本文主要是翻译Rachel Lim的一篇有关MVVM模式介绍的博文 A Simple MVVM Example 并具体给出了一个简单的Demo(原文是以WPF开发的,对于我自己添加或修改的一部分会用红 ...
- MVVM开发模式简单实例MVVM Demo【续】
本文将接着上篇文章,介绍一下三点:(Universal App) 1.将添加Product集合,绑定到列表 2.给点击ListBox的添加选项改变时的事件(要附加依赖属性,和Button点击事件不同) ...
- 精通MVC网站、MVVM开发模式、Razor语法
http://www.cnblogs.com/powertoolsteam/p/MVC_one.html ASP.NET MVC (一)——深入理解ASP.NET MVC 以下是ASP.NET MVC ...
- 从MVC -> MVVM ? 开发模式
MVVM 到底是什么? view :由 MVC 中的 view 和 controller 组成,负责 UI 的展示,绑定 viewModel 中的属性,触发 viewModel 中的命令: viewM ...
- Android开发模式之MVC,MVP和MVVM的简单介绍与区别
相信大家对MVC,MVP和MVVM都不陌生,作为三个最耳熟能详的Android框架,它们的应用可以是非常广泛的,但是对于一些新手来说,可能对于区分它们三个都有困难,更别说在实际的项目中应用了,有些时候 ...
- IOS 与ANDROID框架及应用开发模式对照一
IOS 和ANDROID操作系统都是眼下流行的移动操作系统,被移动终端和智能设备大量採用,两者都採用了先进的软件技术进行设计,为了方便应用开发两者都採用了先进的设计模式. 两者在框架设计上都採用了什么 ...
- Android 当打开“开发人员模式”中的“不保留活动”后,程序应当怎么保持正常执行
Android 当打开"开发人员模式"中的"不保留活动"后,程序应当怎么保持正常执行咧. .? 在这几天,我一直在纠结这个问题.从发现,程序出现这个问题,是由于 ...
随机推荐
- rabbimq 生产消费者
composer.json { "require": { "php-amqplib/php-amqplib": "^2.9" } } com ...
- Python学习记录6-list、tuple、dict、set复习
数据类型在一门语言中是非常重要的,所以选择再次学习一下加深记忆.本次主要参考了大神廖雪峰的官方网站,非常感谢大神,讲的很清晰,收获很大. 标准数据类型 Number(数字) String(字符串) L ...
- [Abp vNext微服务实践] - 添加中文语言
简介 abp vNext中提供了多语言功能,默认语言是英文,没有提供中文语言包.在业务开发中,定义权限后需要用中文的备注提供角色选择,本篇将介绍如何在abp vNext中加入中文语言. step1:添 ...
- C#的Lazy与LazyInitializer
class Program { static void Main(string[] args) { //初始化 Lazy 类的新实例 //当延迟初始化发生时,将使用指定的初始化函数和初始化模式 // ...
- HandlerMethodArgumentResolver完美解决 springmvc注入参数多传报错
作为一个后端开发,能友好兼容前端参数传入错误等问题,在前端发布不小心多传一个参数导致系统错误的问题,一个广告系统是零容忍的,所以为了不犯错误,后端接收参数必须摒弃spring 的自动注入@Reques ...
- HashMap 和 Hashtable 有什么区别?(未完成)
HashMap 和 Hashtable 有什么区别?(未完成)
- 牛客练习赛53 A 超越学姐爱字符串 (DP)
牛客练习赛53 超越学姐爱字符串 链接:https://ac.nowcoder.com/acm/contest/1114/A来源:牛客网 超越学姐非常喜欢自己的名字,以至于英文字母她只喜欢" ...
- 使用PHP读取PHP文件并输出到屏幕上
看完这篇文章,你一定忘不掉htmlentities的用法 背景 今天有个需求,就是一个PHP开发的网址中,有一个页面可以提供给用户修改已经存在的PHP文件中的代码,并POST到服务器上保存. 每次将读 ...
- 创建节点--DOM树
创建节点 快捷键:innerhtml outerhtml innertext outertext ==============创建节点方法有两种:============== <script s ...
- Luogu P2324 [SCOI2005]骑士精神 搜索
刚开始写了个没迭代的...结果过了$qwq$ 然后迭个代..更快了.. #include<cstdio> #include<iostream> #define R regist ...