深入理解與運行Android Jetpack組件之ViewModel
什么是ViewModel
ViewModel是Android Jetpack組件之一,它的主要目的是將UI控制器(如Activity和Fragment)與數(shù)據(jù)相關(guān)的業(yè)務(wù)邏輯分開,使得UI控制器能夠?qū)W⒂谡故緮?shù)據(jù)和響應(yīng)用戶交互,而數(shù)據(jù)的獲取和處理則交由ViewModel來管理。這種分離能夠使代碼更加清晰、易于測試和維護。
ViewModel的原理
ViewModel的原理其實并不復(fù)雜。在設(shè)備配置發(fā)生變化(如屏幕旋轉(zhuǎn))導致Activity或Fragment重建時,ViewModel不會被銷毀,而是保留在內(nèi)存中。這樣,UI控制器可以在重建后重新獲取之前的ViewModel實例,并繼續(xù)使用其中的數(shù)據(jù),從而避免數(shù)據(jù)丟失和重復(fù)加載。
ViewModelStore和ViewModelStoreOwner
ViewModel的原理涉及兩個核心概念:ViewModelStore和ViewModelStoreOwner。
ViewModelStore是一個存儲ViewModel實例的容器,它的生命周期與UI控制器的生命周期關(guān)聯(lián)。在UI控制器(Activity或Fragment)被銷毀時,ViewModelStore會清理其中的ViewModel實例,避免內(nèi)存泄漏。
ViewModelStoreOwner是擁有ViewModelStore的對象,通常是Activity或Fragment。ViewModelProvider通過ViewModelStoreOwner來獲取ViewModelStore,并通過ViewModelStore來管理ViewModel的生命周期。
ViewModelProvider
ViewModelProvider是用于創(chuàng)建和獲取ViewModel實例的工具類。它負責將ViewModel與ViewModelStoreOwner關(guān)聯(lián),并確保ViewModel在合適的時機被銷毀。
在Activity中獲取ViewModel實例:
viewModel = new ViewModelProvider(this).get(MyViewModel.class);
在Fragment中獲取ViewModel實例:
viewModel = new ViewModelProvider(this).get(MyViewModel.class);
使用ViewModel
添加ViewModel依賴
首先,確保你的項目已經(jīng)使用了AndroidX,并在build.gradle中添加ViewModel依賴:
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1" }
創(chuàng)建ViewModel
創(chuàng)建ViewModel非常簡單,只需繼承ViewModel類并在其中定義數(shù)據(jù)和相關(guān)操作。
public class MyViewModel extends ViewModel { private MutableLiveData<String> data = new MutableLiveData<>(); public LiveData<String> getData() { return data; } public void fetchData() { // 模擬異步數(shù)據(jù)獲取 new Handler().postDelayed(() -> { data.setValue("Hello, ViewModel!"); }, 2000); } }
在UI控制器中使用ViewModel
在Activity或Fragment中獲取ViewModel的實例,并觀察數(shù)據(jù)變化:
viewModel = new ViewModelProvider(this).get(MyViewModel.class); viewModel.getData().observe(this, data -> { // 更新UI textView.setText(data); }); viewModel.fetchData(); // 觸發(fā)數(shù)據(jù)獲取操作
ViewModel與跨組件通信
ViewModel不僅僅用于在單個UI控制器內(nèi)部共享數(shù)據(jù),它還可以用于在不同UI控制器之間共享數(shù)據(jù),實現(xiàn)跨組件通信。例如,一個Fragment中的數(shù)據(jù)可以通過ViewModel傳遞給Activity。
在Activity中共享數(shù)據(jù):
sharedViewModel = new ViewModelProvider(this).get(SharedViewModel.class); sharedViewModel.getData().observe(this, data -> { // 更新UI textView.setText(data); });
在Fragment中共享數(shù)據(jù):
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
注意:在跨組件通信時,需要使用同一個ViewModelProvider獲取相同類型的ViewModel實例。在Activity中,使用this作為ViewModelProvider的參數(shù),在Fragment中,使用requireActivity()作為參數(shù)。
ViewModel與SavedState
有時,我們可能希望在ViewModel中保存一些與UI控制器生命周期無關(guān)的數(shù)據(jù),以便在重建時恢復(fù)狀態(tài)。ViewModel提供了SavedState功能,它可以讓我們在ViewModel中持久化保存數(shù)據(jù)。
示例代碼:
public class MyViewModel extends ViewModel { private SavedStateHandle savedStateHandle; public MyViewModel(SavedStateHandle savedStateHandle) { this.savedStateHandle = savedStateHandle; } public LiveData<String> getData() { return savedStateHandle.getLiveData("data"); } public void setData(String data) { savedStateHandle.set("data", data); } }
使用SavedStateViewModelFactory創(chuàng)建帶有SavedState功能的ViewModel:
public class MyActivity extends AppCompatActivity { private MyViewModel viewModel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewModelProvider.Factory factory = new SavedStateViewModelFactory(getApplication(), this); viewModel = new ViewModelProvider(this, factory).get(MyViewModel.class); viewModel.getData().observe(this, data -> { // 更新UI textView.setText(data); }); if (savedInstanceState == null) { // 第一次創(chuàng)建時,觸發(fā)數(shù)據(jù)獲取操作 viewModel.fetchData(); } } }
ViewModel使用過程中的注意點
- 不要在ViewModel中持有Context的引用,避免引發(fā)內(nèi)存泄漏。
- ViewModel應(yīng)該只關(guān)注數(shù)據(jù)和業(yè)務(wù)邏輯,不應(yīng)處理UI相關(guān)的操作。
- 不要在ViewModel中保存大量數(shù)據(jù),避免占用過多內(nèi)存。
- 當數(shù)據(jù)量較大或需要跨進程共享數(shù)據(jù)時,應(yīng)該考慮使用其他解決方案,如Room數(shù)據(jù)庫或SharedPreferences。
結(jié)論
通過本文的介紹,你已經(jīng)了解了Android Jetpack ViewModel的使用與原理。ViewModel的出現(xiàn)極大地簡化了Android開發(fā)中的數(shù)據(jù)管理和生命周期處理,使得應(yīng)用更加健壯和高效。在實際開發(fā)中,合理使用ViewModel能夠幫助你構(gòu)建優(yōu)雅、易維護的Android應(yīng)用。
以上就是深入理解與運行Android Jetpack組件之ViewModel的詳細內(nèi)容,更多關(guān)于Android Jetpack ViewModel的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android 仿小米鎖屏實現(xiàn)九宮格解鎖功能(無需圖片資源)
最近公司要求做個九宮格解鎖,本人用的是小米手機,看著他那個設(shè)置鎖屏九宮格很好看,就做了該組件,不使用圖片資源,純代碼實現(xiàn),感興趣的朋友參考下吧2016-12-12Android開發(fā)中優(yōu)秀的app 異常處理機制
這篇文章主要介紹了Android開發(fā)中優(yōu)秀的app 異常處理機制 的相關(guān)資料,需要的朋友可以參考下2015-12-12Android獲取RecyclerView滑動距離方法詳細講解
RecyclerView是Android一個更強大的控件,其不僅可以實現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實現(xiàn)數(shù)據(jù)縱向滾動,也可以實現(xiàn)橫向滾動(ListView做不到橫向滾動)。接下來講解RecyclerView的用法2023-01-01