天天看點

JetPack初探之ViewModelJetPack初探之ViewModel

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資料變化進行觀察并随之變化。