MVVM架构篇之DataBinding(-)

3,381 阅读8分钟

1.前言

2.简述MVC,MVP

3.什么是MVVM

4.什么是DataBinding

5.简单例子

6.总结

=================================================

1.前言

在2015年谷歌I/O大会上介绍了一个新的框架,就是DataBinding,而DataBinding是什么呢?根据英文翻译成中文就是数据绑定。

2.简述MVC,MVP

说DataBinding之前先说一下什么是MVVM?从Android诞生到现在已经十多年,也陆陆续续出现了现在最主流的MVC,MVP,MVVM三大代码架构开发模式。下面简单分析下这三者开发模式的特点和优缺点。

MVC

MVC全名是Model View Controller是模型(model),视图(view),控制器(controller)的缩写。

M:Model是对应用状态和业务功能的封装,可以将它理解为同时包含数据和行为的领域模型,通常模型对象负责在数据库中存取数据。

V:View是应用程序中处理数据显示的部分,就是实现可视化界面的呈现并捕捉用户的交互操作,在Android中,他可以是一个Activity,一个Fragment,一个Dialog。View可以直接调用Model查询状态信息,Model也可以在自己的状态发生改变时,主动通知View。通常视图是依据模型数据创建的。

C:Controller是应用程序中处理用户交互的部分。是M和V之间的连接器,用于控制应用程序的流程。View捕获用户交互操作后直接发给Controller,后者完成相应的UI逻辑。如果需要涉及业务功能的调用,Controller会直接调用Model及修改Model状态。Controller也可以主动控制原View或者创建新的View对用户交互操作予以回应。通常控制器负责从视图读取数据,控制用户的输入,并向模型发送数据。

下面通过一张图来显示这三者的关系:

mvc图.png

发现MVC,View是可以直接访问Model,那么View里会包含Model的信息,不可避免的也包含一些业务逻辑。在MVC模型里,更关注的Model改变,而同时有多个对Model的不同显示,即View。所以,在MVC模型里,Model不依赖于View,但View是依赖于Model。那么现在想想,对Android来说,activity基本承担来view层和controller层两种角色,并且和model层耦合严重,在逻辑复杂的界面维护起来很麻烦。那么这时候MVP出来来,切断View和Model之间的关系。

MVP

MVP全名是Model-View-Presenter是模型(model),视图(view),展示器(presenter)的缩写。

M和V上面已经解释过来,现在解释p:presenter Presenter是从Model中获取数据并提供给View层,简单的就是当View需要去更新数据时,首先找Presenter,Presenter然后去向Model请求数据,从Model获取数据之后通知Presenter,Presenter再通知View去更新数据。简而言之:返回什么数据给View。

下面通过一张图来显示这三者的关系:

MVP图.png

从上图可以看出MVP的优点:

1.严格禁止View和Model间的交互,必需通过Presenter来完成。Model的独立性得到来真正的体现,它不仅仅与可视化元素(View)的呈现无关,与UI处理逻辑也无关,使用MVP的应用是用户驱动而不是Model驱动,所以Model不需要主动通知View。

2.MVP模式中的V代表的是一个接口,一个将UI界面提炼而抽象出来的接口。接口意味着任何实现来该接口的界面都能够复用已有的Presenter和Model代码。是真正意义上的隔离View的细节和复杂性的模式,降低来Presenter对View的依赖。好处就是在Presenter的UI处理逻辑变得易于测试。

3.什么是MVVM

如果说MVP是对MVC的进一步改进,那么MVVM则是思想上的完全变革。 MVVM全称是Model-View-ViewModel。

MVVM类型MVC和MVP,但是比这两个更加强大。MV-VM对比MVP,实际上就是将Presenter层替换成了ViewModel层。MVVM是以“数据模型数据双向绑定”的思想作为核心,因此在View和Model之间没有联系,而是通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的,因此视图数据的变化会同时 修改数据源,而且数据源数据的变化也会立即反应到View上。

ViewModel层所需要做的就是完全跟逻辑相关的代码,完全不涉及到UI,当数据变化时,直接驱动UI的改变,中间省去了冗余的接口,在ViewModel层编写代码中,要求开发者需要将每个方法尽可能做的功能单一,不与外部有任何的联系,提高了代码的健壮性方便后期的单元测试。

同样下面通过一张图来显示三者的关系:

MVVM图.png

其实除了非常熟悉的Model,View和ViewModel这三个部分,在MVVM的实现中,还引入来隐式的一个Binder层,而声明式的数据和命令的绑定在MVVM模式中就是通过它来完成的。

MVVM之BInder层.png

从MVC架构模式到MVVM,从分离层到展示模型层,经过几十年的发展,MVC架构模式出现了各种各样的变种,并且在不同的平台上有着自己的实现,开发者可以根据现实的情况去和各自的优缺点采取用什么模式进行开发。

4.什么是DataBinding

上面说到MVVM是以“数据模型数据为绑定”的思想为核心,View和ViewModel会有一个隐式的BInder层。而他们是以什么来实现单向或者双向绑定呢?就是通过DataBinding这个框架来实现的,是实现UI和数据绑定的框架,做到UI和数据的相互监听,开发者的任务分配很明确,负责ViewModel的开发者不用考虑UI怎么实现的,提高来代码的开发效率和后期出现问题跟踪的准确性。

5.简单例子

下面通过一个小例子来入门DataBinding

环境要求

  • DataBinding是一个support library,最低要求Android2.1
  • Android stdio版本1.3以上
  • gradle插件1.5以上

gradle配置

在module级别的build.gradle上添加DataBinding的支持: 注意:如果要在library中使用,那么使用该library也要在build.gradle添加支持。

android{
   dataBinding{
          enabled = true
     }
}

创建对象

下面创建一个名为User的对象

 public class User {
    //名字
    private String name;
    //是否男的
    private boolean isMale;
    //年龄
    private int age;

    public String getName() {
        return name;
    }

    public User(String name, boolean isMale, int age) {
        this.name = name;
        this.isMale = isMale;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isMale() {
        return isMale;
    }

    public void setMale(boolean male) {
        isMale = male;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

布局文件的填写

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="user"
            type="com.android.databinding.User" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}" />


        <!-- boolean 要转为String来显示 不然编译异常-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(user.isMale)}" />
        <!-- age是int类型 必须转化为String 不然编译异常-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(user.age)}" />

    </LinearLayout>
</layout>

可以看到布局文件和之前的xml不同,根节点变成了layout,而在layout的子节点中分成两部分,第一部分是data节点,data表示创建变量,data的节点作用是连接View和Model的桥梁;而第二部分才是之前开发的根节点。在data节点下又定义了一个variable,variable表示声明的变量,其中name表示变量名,type表示变量类型,这样值就可以轻松传到布局文件中。注意控件TextView没有定义id,是在text的时候用了@{}(用@{bean.xxx})的这样的语法表达式和数据user实现绑定。

Activity文件

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        User user = new User("狗狗",true,24);
        binding.setUser(user);
    }
}

发现没有了控件的初始化findViewById或者butterknife,也没有控件的设置数据。绑定布局文件由DataBindingUtil.setContentView代替setContentView。通过binding.setUser(Bean)和variable进行绑定。 注意:在/build/generated/source/apt/debug/comapt/debug/com.android.databinding/databinding/可以看到ActivityMainBinding。这个类的生成的规则是activity_main --> ActivityMainBinding,fragment_main --> FragmentMainBinding。就是第一个单词首字母大写,第二个单词首字母大写,最后都会拼上Binding。 实际结果如下:

实践结果.png

1. 配置了dataBinding{enabled = true}之后就可以使用databinding方式进行开发?

Android Stdio中是靠gradle来管理构建项目的,我们知道一个项目的构建需要执行很多的task(任务),有很多task系统预先定义好的,如:build task,clean task。而Databinding task也是系统预先定义的,在默认情况下,我们没有开启dataBinding{enable = true},因此没有在task列表里,当我们开启dataBinding后,就会执行相关的task来检查并且生成dataBinding相关的代码。

2.ActivityMainBinding这个类怎么生成的?

这个类是系统自动生成的,默认情况下,系统会使用Android Stdio为我们自动生成的databinding相关的代码,但是你会发现不能看到源码。可以在上面所说的build路径下进行源码查看或者手动编译代码。

6.总结

dataBinding主要的优势在于减少Activity和Fragment层的代码,不再使用findViewById,xml文件从之前的展示布局到现在可以进行一些操作。这篇文章只是初识DataBinding,后面会陆续讲解它的运用。