Android之MVVM开发模式

摘要:
MVVM模式下的视图完全抽象了视图的状态和行为,并将逻辑和接口的控制权完全交给了ViewModel。在Google IO2017中,Google发布了官方应用程序架构库ArchitectureComponents。该架构库是谷歌对Android应用程序架构的推荐,也称为官方Android应用架构指南。Android架构组件可以在谷歌的中国开发者网站上找到。结合Android程序的特点,它总体上类似于微软MVVM,但做了更详细的模块划分。Android中的数据绑定技术由DataBinding和LiveData联合实现。

MVVM 模式简介

MVVM模式是指Model-View-ViewModel。相信看过笔者关于MVP的文章的读者也会发现,无论如何抽象化,在我们的View层中是无法避免的要处理一部分逻辑的。而MVVM模式中的View是将View的状态和行为完全抽象化,把逻辑与界面的控制完全交给ViewModel处理。Android之MVVM开发模式第1张
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类似,但是做了更细致的模块划分。

Android之MVVM开发模式第2张
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的方法。


数据对象

packagecom.loaderman.modedemo;
public classUser {
    publicString name;
}

事件绑定对象

packagecom.loaderman.modedemo;
importandroid.view.View;
importandroid.widget.TextView;
importandroid.widget.Toast;
public classmyHandlers  {
    public voidonClickName(View view){
        TextView view1 =(TextView) view;
        Toast.makeText(view.getContext(),view1.getText().toString(),Toast.LENGTH_SHORT).show();
    }
}

MainActivty.java

packagecom.loaderman.modedemo;
importandroid.databinding.DataBindingUtil;
importandroid.os.Bundle;
importandroid.support.v7.app.AppCompatActivity;
importandroid.view.View;
importcom.loaderman.modedemo.databinding.ActivityMainBinding;
public class MainActivity extendsAppCompatActivity {
    User user;
    privateActivityMainBinding dataBinding;
    @Override
    protected voidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        user = newUser();
        dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        findViewById(R.id.btn).setOnClickListener(newView.OnClickListener() {
            @Override
            public voidonClick(View view) {
                //模拟数据更新
                user.name = "android ";
                dataBinding.setUser(user);
            }
        });
        user.name = "loaderman";
        //数据绑定
dataBinding.setUser(user);
        //事件绑定
        dataBinding.setMyHandlers(newmyHandlers());
    }
}

在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开发模式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇开源分布式文件系统比较50+道大厂JVM面试题 + 11张思维导图就是让你懂JVM~下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Android 上的 10 款 Web 开发工具推荐

作为一个狂热的 Android 用户,我一直在寻找适合Web开发人员使用的一些应用程序。经过搜索发现能够找到Web开发几乎每个方面的工具,涉及从Web服务器本身到FTP客户端再到一个源代码查看器,以及网站分析工具等等。以下推荐10款非常实用的Android端的Web开发工具。1.AndFTPAndFTP 是 Android 手机上的支持 FTP、SFTP、...

android中的内部存储与外部存储

我们先来考虑这样一个问题: 打开手机设置,选择应用管理,选择任意一个App,然后你会看到两个按钮,一个是清除缓存,另一个是清除数据,那么当我们点击清除缓存的时候清除的是哪里的数据?当我们点击清除数据的时候又是清除的哪里的数据?读完本文相信你会有答案。 在android开发中我们常常听到这样几个概念,内存,内部存储,外部存储,很多人常常将这三个东西搞混,那么...

NDK笔记(二)-在Android Studio中使用ndk-build(转)

前面一篇我们接触了CMake,这一篇写写关于ndk-build的使用过程。刚刚用到,想到哪儿写哪儿。 环境背景 Android开发IDE版本:AndroidStudio 2.2以上版本(目前已经升级到2.2.3) 计算机环境:Window 64位系统 Demo工程的创建与设置 1.新建一个工程,并在app/src/main路径下新建jni文件夹。 2.在...

Android 4.0 SDK的离线方式安装(转)

转自:http://networking.ctocio.com.cn/110/12195610.shtml  作 为一个IT技术人员,迫不及待地就奔向了http://developer.android.com去看看有没有新的SDK公布出来,当时是上午,没见到 有更新,心想一定是若干天后才会发布。没想到同事下午告诉我,新版的SDK已经发布了。当时是临下班,...

七 APPIUM Android 定位方式

1.定位元素应用元素   1.1通过id定位元素 Android里面定位的id一般为resrouce-id: 代码可以这样写: WebElement element = driver.findElement(By.id("com.tencent.mm:id/do")); 或者: driver.findElementById("com.tencent.mm...

Android编程获取手机型号,本机*,sdk版本号及firmware版本号号(即系统版本号号)

Android开发平台中,可通过TelephonyManager 获取本机号码。 TelephonyManager phoneMgr=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); txtPhoneNumber.setText(phoneMgr.getLine1Num...