欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android Jetpack架構(gòu)組件 ViewModel詳解

 更新時間:2020年07月14日 14:22:28   作者:黃林晴  
這篇文章主要介紹了Android Jetpack架構(gòu)組件 ViewModel詳解,ViewModel類讓數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后繼續(xù)存在,ViewModel類旨在以注重生命周期的方式存儲和管理界面相關(guān)的數(shù)據(jù)。感興趣可以來學(xué)習(xí)一下

前言

前面兩篇文章我們已經(jīng)學(xué)習(xí)了Lifecycle和DataBind,本篇文章我們來學(xué)習(xí)Jetpack系列中比較重要的ViewModel,Jetpack的很多很多組件都是搭配使用的,所以單獨的知識點可能會有些”無意義“但卻是我們項目實戰(zhàn)的基礎(chǔ)!

ViewModel的使用

ViewModel類旨在以注重生命周期的方式存儲和管理界面相關(guān)的數(shù)據(jù)。ViewModel類讓數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后繼續(xù)存在。這句話很好理解,還記得我們在講解Lifecycle的時候 舉的例子嗎,我們還是使用那個例子,如果你還沒看過,可移步至:

Android Jetpack系列之Lifecycle

我們再回顧一次需求:

在Activity 可見的時候,我們?nèi)プ鲆粋€計數(shù)功能,每隔一秒 將計數(shù)加1 ,當(dāng)Activity不可見的時候停止計數(shù),當(dāng)Activity被銷毀的時候 將計數(shù)置為0,這里我們在Activity被銷毀的時候不再將count置為0,WorkUtil代碼如下所示:

public class WorkUtil implements LifecycleObserver {
 
 
 private static final String TAG = "WorkUtil";
 
 private boolean whetherToCount = true;
 
 private int count = 0;
 
 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
 public void start() {
 new Thread(new Runnable() {
  @Override
  public void run() {
  while (whetherToCount) {
   try {
   Thread.sleep(1000);
   count++;
   Log.d(TAG, "start: " + count);
   } catch (InterruptedException e) {
   e.printStackTrace();
   }
  }
  }
 }).start();
 }
 
 @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
 public void onStop() {
 whetherToCount = false;
 Log.d(TAG, "onStop: ");
 }
 
 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
 public void onDestory() {
 }
}

我們運行程序,在計數(shù)的過程中 使屏幕旋轉(zhuǎn),運行結(jié)果如下所示:

我們可以看到,當(dāng)屏幕旋轉(zhuǎn)的時候,由于生命周期發(fā)生了改變,導(dǎo)致數(shù)據(jù)被銷毀,所以計數(shù)器的計數(shù)又從初始值開始計數(shù)了,那么我們?nèi)绾谓鉀Q這個問題呢,你肯定會說,緩存呀,重寫onSabeInstanceState()方法等等,都可以但是都不夠優(yōu)雅,那么如何優(yōu)雅的來解決這個問題呢,這就是我們的今天的主角  ViewModel。

ViewModel的使用

我們新建Main3ActivityModel 繼承自 ViewModel,在Main3ActivityModel中定義count變量 如下所示:

public class Main3ActivityViewModel extends ViewModel {
 
 public int count = 0;
 
}

沒錯,就是這么簡單,我們只要保證計數(shù)的變量是這個model中的變量,就可以解決我們上面的問題

我們通過ViewModelProviders來獲取ViewModel對象

main3ActivityViewModel = ViewModelProviders.of(this).get(Main3ActivityViewModel.class);

但是這個方法已經(jīng)過時了,替代方法是

main3ActivityViewModel = new ViewModelProvider(this).get(Main3ActivityViewModel.class);

為了讓W(xué)orkUtil使用Model中的變量,所以我們要將ViewModel 傳遞過去,在WorkUtil中新增一個構(gòu)造方法

private Main3ActivityViewModel main3ActivityViewModel;
 
public WorkUtil(Main3ActivityViewModel main3ActivityViewModel) {
 this.main3ActivityViewModel = main3ActivityViewModel;
}

我們將WorkUtil中的計數(shù)變量count 改為 main3ActivityViewModel.count,如下所示:

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void start() {
 new Thread(new Runnable() {
 @Override
 public void run() {
  while (whetherToCount) {
  try {
   Thread.sleep(1000);
   main3ActivityViewModel.count++;
   Log.d(TAG, "start: " + main3ActivityViewModel.count);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  }
 }
 }).start();
}

main3Activity中在lifecycle中傳參:

getLifecycle().addObserver(new WorkUtil(main3ActivityViewModel));

再次運行程序,運行過程中旋轉(zhuǎn)手機屏幕,打印如下所示:

我們可以看到,在屏幕旋轉(zhuǎn)之后,計數(shù)器的計數(shù)保留了,那么viewModel是如何做到的呢,這是因為ViewModel 對象存在的時間比視圖或 LifecycleOwners 的特定實例存在的時間更長,ViewModel的生命周期如下圖所示(摘自官網(wǎng)) 

向ViewModel傳參

當(dāng)前計數(shù)的需求是從0開始計時,我們現(xiàn)在修改需求如下,使用用戶輸入的數(shù)字為起點開始計數(shù),這樣的話ViewModel中的count就不是0了,而是傳入的參數(shù),我們在Main3Activity中定義變量inputCount 來模擬用戶輸入的數(shù)字

private int inputCount = 100;

在Main3ViewModel中添加構(gòu)造方法

public int count = 0;
 
public Main3ActivityViewModel(int count) {
 this.count = count;
}

看到這里,你可能會說,我們直接new一個傳過去不就行了嗎,請記住這是萬萬不行的,因為如果我們使用直接實例化來創(chuàng)建ViewModel,那么ViewModel的生命周期就受Activity的影響了,所以為什么我們只能通過ViewModelProvider來獲取ViewModel的實例。

我們需要借助ViewModelProvider.Factory來實現(xiàn)傳參,新建Main3ActivityViewModelFactor繼承自 ViewModelProvider.Factory,重寫其onCreate方法,如下所示:

public class Main3ActivityViewModelFactory implements ViewModelProvider.Factory {
 
 @NonNull
 @Override
 public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
 return null;
 }
}

添加一個構(gòu)造方法,并在create中創(chuàng)建VideModel實例

private int count;
 
public Main3ActivityViewModelFactory(int count) {
 this.count = count;
}
 
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
 return (T) new Main3ActivityViewModel(count);
}

在Activity中獲取實例的時候 采用如下方法

main3ActivityViewModel = new ViewModelProvider(this,new Main3ActivityViewModelFactory(inputCount)).get(Main3ActivityViewModel.class);

運行程序,打印結(jié)果如下所示: 

如此一來 我們就實現(xiàn)ViewModel傳遞參數(shù)了~

以上就是Android Jetpack架構(gòu)組件 ViewModel詳解的詳細(xì)內(nèi)容,更多關(guān)于Android Jetpack架構(gòu)組件 ViewModel的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論