Android Jetpack -- ViewModel篇(一)

ViewModel的出現主要爲了解決兩個問題:
1.當Actvitiy銷燬重建過程當中的數據恢復問題,雖然原來可使用onSaveInstanceState()來完成,可是隻支持能被序列化的數據並且是小量數據,對於大量數據則顯得有點無力。
2.UI控制器的工做繁忙,UI控制器主要用於處理顯示,交互,其餘的額外操做能夠委託給其餘類完成,將不該該分配給UI的任務分離出來是必要的,這也就是上面所說的分離關注點原則。
下面是示意圖html

ViewModel實例

ViewModel在配置更改期間能自動保留其對象,以便它們所持有的數據可當即用於下一個 Activity 或片斷 Fragment
ide

具體的實例我在之前的一篇博客中講過了,想要了解請點擊  Android學習進度二  進行查看。學習

 

回到最上面的那個圖,圖說明了ViewModel的做用域涉及到整個生命週期,當獲取ViewModel時,ViewModel的生命週期限定爲傳入ViewModelProvider的對象的生命週期。也就是對於如下場景(引用官方示例)this

public class SharedViewModel extends ViewModel {          private final MutableLiveData<Item> selected = new MutableLiveData<Item>();  
         public void select(Item item) {   selected.setValue(item);   }  
         public LiveData<Item> getSelected() {              return selected;   }   }  
     public class MasterFragment extends Fragment {          private SharedViewModel model;          public void onCreate(Bundle savedInstanceState) {              super.onCreate(savedInstanceState);              model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);              itemSelector.setOnClickListener(item -> {   model.select(item);   });   }   }  
     public class DetailFragment extends Fragment {          public void onCreate(Bundle savedInstanceState) {              super.onCreate(savedInstanceState);              SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);              model.getSelected().observe(this, { item ->
                // Update the UI.
  });   }   } 

因爲傳入的是Activity,因此其做用域爲整個Activity,不一樣的Fragment能夠經過ViewModelProviders獲取到同一個ViewModel,這樣有如下的好處:spa

  • Activity無須參與Fragment之間的交互。Activity與Fragment無關
  • Fragment之間也無需互相創建聯繫,Fragment與Fragment無關
  • 每一個Fragment都有本身的生命週期,即便被替換也不會有任何影響

ViewModel增強,支持異常生命週期

有些時候在Activity被意外殺死,如清理後臺等會直接跳過onDestory()而是回調onSaveInstanceState()異常殺死下的生命週期,這個時候ViewModel也會被殺死,再次恢復的時候便會被重建,這樣,原來的數據也就丟失了,所以咱們須要改進一下ViewModel以支持異常退出狀況下的重建。
首先很容易是想到經過onSaveInstanceState() 來保存,而後經過SaveInstanceState 來恢復,雖然也是一種可行的方法,可是跟ViewModel沒什麼關聯,ViewModel也提供了相似SavedInstanceState的方法。code

SavedStateHandle :用於保存狀態的數據類型,是一個key-value的map,相似於Bundle。htm

具體用法對象

public class ViewModelWithData extends ViewModel {  
     private MutableLiveData<Integer> number;      private SavedStateHandle handle;  
     private static final String KEY_NUMBER = "number";  
     public ViewModelWithData(SavedStateHandle handle) {          this.handle = handle;          number = new MutableLiveData<>();          number.setValue(0);   }  
     public MutableLiveData<Integer> getNumber() {          if (!handle.contains(KEY_NUMBER)) {              handle.set(KEY_NUMBER, 0);   }          return handle.getLiveData(KEY_NUMBER);   }  
     public void addNumber(int n) {          getNumber().setValue(getNumber().getValue() + n);   }  }
public class LiveDataActivity extends AppCompatActivity {  
     private ViewModelWithData viewModelWithData;  
  ActivityLiveDataBinding binding;  
  @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          binding = DataBindingUtil.setContentView(this, R.layout.activity_live_data);          viewModelWithData = ViewModelProviders.of(this, new SavedStateVMFactory(this)).get(ViewModelWithData.class);   binding.setData(viewModelWithData);          binding.setLifecycleOwner(this);   }  
 }
相關文章
相關標籤/搜索