深入理解與運(yùn)行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來管理。這種分離能夠使代碼更加清晰、易于測試和維護(hù)。
ViewModel的原理
ViewModel的原理其實并不復(fù)雜。在設(shè)備配置發(fā)生變化(如屏幕旋轉(zhuǎn))導(dǎo)致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實例的工具類。它負(fù)責(zé)將ViewModel與ViewModelStoreOwner關(guān)聯(lián),并確保ViewModel在合適的時機(jī)被銷毀。
在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)存。
- 當(dāng)數(shù)據(jù)量較大或需要跨進(jìn)程共享數(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)雅、易維護(hù)的Android應(yīng)用。
以上就是深入理解與運(yùn)行Android Jetpack組件之ViewModel的詳細(xì)內(nèi)容,更多關(guān)于Android Jetpack ViewModel的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android選擇圖片或視頻進(jìn)行循環(huán)播放
這篇文章主要為大家詳細(xì)介紹了Android選擇圖片或視頻進(jìn)行循環(huán)播放,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10
Android 仿小米鎖屏實現(xiàn)九宮格解鎖功能(無需圖片資源)
最近公司要求做個九宮格解鎖,本人用的是小米手機(jī),看著他那個設(shè)置鎖屏九宮格很好看,就做了該組件,不使用圖片資源,純代碼實現(xiàn),感興趣的朋友參考下吧2016-12-12
Android開發(fā)中優(yōu)秀的app 異常處理機(jī)制
這篇文章主要介紹了Android開發(fā)中優(yōu)秀的app 異常處理機(jī)制 的相關(guān)資料,需要的朋友可以參考下2015-12-12
Android獲取RecyclerView滑動距離方法詳細(xì)講解
RecyclerView是Android一個更強(qiáng)大的控件,其不僅可以實現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實現(xiàn)數(shù)據(jù)縱向滾動,也可以實現(xiàn)橫向滾動(ListView做不到橫向滾動)。接下來講解RecyclerView的用法2023-01-01

