1. 程式人生 > >MVVM架構篇之DataBinding(-)

MVVM架構篇之DataBinding(-)

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,後面會陸續講解它的運用。