Android從零開始搭建MVVM架構(2)————ViewModel

在真正接觸並使用MVVM架構的時候,整我的都很差了。由於我的以爲,MVVM相對於MVC、MVP學習難度比較大,設計的知識點不是一點半點。因此想慢慢記錄下本身的成長。若有錯誤但願指正。java


從零開始搭建MVVM架構系列文章(持續更新):
Android從零開始搭建MVVM架構(1)————DataBinding
Android從零開始搭建MVVM架構(2)————ViewModel
Android從零開始搭建MVVM架構(3)————LiveData
Android從零開始搭建MVVM架構(4)————Room(從入門到進階)
Android從零開始搭建MVVM架構(5)————Lifecycles
Android從零開始搭建MVVM架構(6)————使用玩Android API帶你搭建MVVM框架(初級篇)
Android從零開始搭建MVVM架構(7) ———— 使用玩Android API帶你搭建MVVM框架(終極篇)android


仍是那張圖AAC(Android Architecture Components)git

這篇咱們講ViewModel。這裏咱們只是簡單瞭解和認識MVVM中的ViewModel。等把這些組件都認識後,咱們再以wanAndroid api擼一遍正題的MVVM項目。github


1、ViewModel

還記得MVP中的Model嗎。這裏的ViewModel有點相似MVP中的Model的做用。可是google出了一套AAC組件。這些組件讓開發者能開發高效的項目。其中ViewModel也是其中組件之一。api

1.一、爲何會有這個ViewModel組件

簡介:ViewModel是以生命週期的方式存儲與管理UI相關數據
做用
一、在MVVM模式中,使Model與View分離
二、負責爲ui準備數據
三、存儲數據網絡

這裏最大的亮點是以生命週期的方式。舉例:假如在Activity裏使用。他會貫穿整個Activity裏的生命週期。先看張圖:架構

首先把結果先總結如下幾點(後面用例子驗證):app

  • ViewModel只會在Activity存活,且只會建立一次。當銷燬時,會主動調用onClered。

爲何整個生命週期方式很重要?例如:app須要頻繁異步請求數據,好比請求網絡調接口,這些都是至關耗時。好比Activity被銷燬後接口請求才返回,考慮到內存泄漏狀況,會給咱們增添好多複雜工做。但如今咱們利用ViewModel處理數據回調,能夠解決此問題。意思只要繼承咱們的ViewModel後,可能會出現的bug,google都幫咱們處理了。框架

  • 由於在Activity存活時,只建立一次,那麼在此Activity下的全部Fragment均可以共享一個ViewModel
  • 因爲 ViewModel 生命週期可能長與 activity 生命週期,因此爲了不內存泄漏Google禁止在ViewModel中持有Context或activity或view的引用。若是非得使用Context, 能夠繼承AndroidViewModel 類中獲取ApplicationContext
  • 以前咱們在activity銷燬重建時,能夠用activity的onSaveInstanceState()機制保存和恢復數據,但缺點明顯, 只適合保存少許的能夠被序列化、反序列化的數據。假如咱們須要保存一個比較大的數據,這個時候ViewModel就能夠實現。


怎麼看上面的生命週期圖呢
一、Activity created(走了3個生命週期),對應於ViewModel的scope。
二、Activity rorared(相似切換了橫豎屏幕),仍是對應scope
三、finish()(Activity銷燬),依賴是scope
四、Finished (已經銷燬了)。調用ViewModel的onCleared。異步

這樣說很模糊,看一下例子


2、探索ViewModel的生命週期

咱們首先建立咱們的MyViewModel,繼承ViewModel。並重寫onCleared()

public class MyViewModel extends ViewModel {
    @Override
    protected void onCleared() {
        super.onCleared();
        LogUtils.i("MyViewModel的相關","Activity被殺死後也會被銷燬!");
    }
}
複製代碼

點開ViewModel的源碼:

由於這層沒有透露出具體的生命週期綁定和銷燬的具體實現。咱們還要去找實現類。這裏咱們本着簡單使用的原則,那麼我就直接在Activity裏打印MyViewModel的hashCode值來驗證上面的圖,Activity裏的代碼。這裏還要說下,這裏咱們用到了ViewModelProciders類,因此要引入下依賴

implementation 'android.arch.lifecycle:extensions:1.1.1'

public class ViewModelActivity extends FragmentActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_viewmodel);
        MyViewModel myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        LogUtils.i("MyViewModel的相關", "onCreate ==> " + myViewModel.hashCode());
    }

    @Override
    protected void onStart() {
        super.onStart();
        MyViewModel myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        LogUtils.i("MyViewModel的相關", "onStart ==> " + myViewModel.hashCode());
    }

    @Override
    protected void onResume() {
        super.onResume();
        MyViewModel myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        LogUtils.i("MyViewModel的相關", "onResume ==> " + myViewModel.hashCode());
    }

    @Override
    protected void onPause() {
        super.onPause();
        MyViewModel myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        LogUtils.i("MyViewModel的相關", "onPause ==> " + myViewModel.hashCode());
    }

    @Override
    protected void onStop() {
        super.onStop();
        MyViewModel myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        LogUtils.i("MyViewModel的相關", "onStop ==> " + myViewModel.hashCode());
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        MyViewModel myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        LogUtils.i("MyViewModel的相關", "onDestroy ==> " + myViewModel.hashCode());
    }
}
複製代碼

運行項目後,看打印;這裏能夠看到,hashCode值都是同樣的。:

接着咱們讓手機橫豎切換下,看打印。一樣能夠看到hashCode值是同樣的,沒有改變:

最後,咱們退出這個頁面,看打印。這裏在調用了ViewModel的onCleared後銷燬後,hashCode值才從新建立。這裏惟一疑點是,這裏和官網圖有些不一樣,ViewModel的銷燬onClered,在Ondestroy的前一步(只是和圖解效果有差別,可是流程是對的,若有小夥伴對這塊熟悉,請指點下):


3、與Fragment間共享數據

好比咱們Activity裏還展現了不少個Fragment。咱們這裏只須要看一段Fragment裏的代碼就清楚了

//從getActivity()這句,那可不是同一個MyViewModel嗎。
ViewModelProviders.of(getActivity()).get(MyViewModel.class)
複製代碼

至此這裏對簡單的ViewModel作了簡單介紹,和使用。讓咱們一塊兒慢慢實現本身的MVVM框架把!!

本文demo地址

相關文章
相關標籤/搜索