JetPack初探之ViewModel
簡介
-
官方介紹:
ViewModel is a class that is responsible for preparing and managing the data foran Activity} or a {@link androidx.fragment.app.Fragment Fragment}.
It also handles the communication of the Activity / Fragment with the rest of the application
(e.g. calling the business logic classes).
-
直譯:
ViewModel是一個負責為Activity或Fragment準備和管理資料的類。它還處理Activity / Fragment與應用程式其餘部分的通信
viewModel使用
- 建立MyViewModel()類,讓它繼承ViewModel()。
-
在Activity/Fragment中使用val viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java),擷取到viewModel執行個體。
viewModel可以用來存儲與viewModel綁定的view層的資料,如果在使用viewModel期間,将裝置旋轉(橫屏/豎屏),view層會被重新建立,但是viewModel會繼續被新建立的view持有。
以上是對viewModel的最基本建立及使用,如果需要更加仔細的則需要在viewModel中配合LiveData或其他Jetpack元件。
源碼探究
1.ViewModel()的建立:在MyViewModel()類中Ctrl+右鍵,進入ViewModel(),在ViewModel類中,官方給了viewModel的簡介,使用方法,以及使用viewModel在fragment之間進行資料互動
然後看onCleared()方法,當你的viewModel不再使用時會調用這個方法
2.然後是ViewModelProviders()類中有4個of方法,他們的作用都是:建立一個ViewModelProvider,他能在fragment/Activity給定的生命周期内儲存ViewModel。
//這兒隻舉例fragment
public static ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) {
Application application = checkApplication(checkActivity(fragment));
if (factory == null) {
//擷取AndroidViewModelFactory
//AndroidViewModelFactory作用:建立AndroidViewModel和ViewModel,
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
//fragment.getViewModelStore():擷取view層的viewModelStore
//factory:它将被用來執行個體化新的viewmodel
return new ViewModelProvider(fragment.getViewModelStore(), factory);
}
其中factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);的作用:建立AndroidViewModel和ViewModel,擷取一個有效的AndroidViewModelFactory
點選檢視new ViewModelProvider(activity.getViewModelStore(), factory)的ViewModelProvider類中。可以看到在get()方法中
@NonNull
@MainThread
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
ViewModel viewModel = mViewModelStore.get(key);
if (modelClass.isInstance(viewModel)) {
//noinspection unchecked
return (T) viewModel;
} else {
//noinspection StatementWithEmptyBody
if (viewModel != null) {
// TODO: log a warning.
}
}
if (mFactory instanceof KeyedFactory) {
viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
} else {
viewModel = (mFactory).create(modelClass);
}
mViewModelStore.put(key, viewModel);//将viewModel放入ViewModelStore中
//noinspection unchecked
return (T) viewModel;
}
将你的ViewModel存入ViewModelStore中,對應的Key是(DEFAULT_KEY + “:” + canonicalName)
- DEFAULT_KEY = “androidx.lifecycle.ViewModelProvider.DefaultKey”
- canonicalName = modelClass.getCanonicalName();//MyViewModel的檔案所在位置如:com.android.test.viewmodel.MyViewModel
3.ViewModelStore:必須通過配置更改來保留{ViewModelStore}的一個執行個體:如果這個{ViewModelStore}的所有者由于配置更改而被銷毀并重新建立,那麼所有者的新執行個體應該仍然擁有相同的{ViewModelStore}的舊執行個體。
viewModelStore是通過HashMap對ViewModel進行存取操作。
put(String key, ViewModel viewModel)//存儲VIewModel
get(String key)//擷取已存在的ViewModel
clear() //清除内部存儲并通知viewmodel它們不再被使用。
總結
viewModel的基本情況就是這樣,它配合LiveData可以對ViewModel中的LiveData資料變化進行觀察并随之變化。