溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android 中ViewModel組件如何使用

發布時間:2021-08-12 11:33:55 來源:億速云 閱讀:285 作者:Leah 欄目:移動開發

本篇文章給大家分享的是有關Android 中ViewModel組件如何使用,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

1. 依賴庫

implementation "androidx.fragment:fragment:1.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:2.0.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"

2. 主要類與接口

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProvider.Factory;
import androidx.lifecycle.ViewModelProviders;
import androidx.lifecycle.ViewModelStore;
import androidx.lifecycle.ViewModelStoreOwner;

3. ViewModel

ViewModel 是一個抽象類,類中只定義了一個空實現的 onCleared() 方法。

    @SuppressWarnings()
    {
    }
}
3.1 AndroidViewModel

AndroidViewModel 類擴展了 ViewModel 類,增加了 Application 字段,在構造方法初始化,并提供了 getApplication() 方法。

public class AndroidViewModel extends ViewModel {
    private Application mApplication;

    public AndroidViewModel(@NonNull Application application) {
        mApplication = application;
    }

    /**
     * Return the application.
     */
    @NonNull
    public 

4. 獲取和創建過程分析

獲取 ViewModel 對象代碼如下:

ViewModelProviders.of(activityOrFragment).get(ViewModel::class.java)

4.1 ViewModelProviders

ViewModelProviders 類提供了4個靜態工廠方法 of() 創建新的 ViewModelProvider 對象。

ViewModelProviders.of(Fragment)
ViewModelProviders.of(FragmentActivity)
ViewModelProviders.of(Fragment, Factory)
ViewModelProviders.of(FragmentActivity, Factory)

4.2 ViewModelProvider

ViewModelProvider 負責提供 ViewModel 對象,類中定義了以下兩個字段:

private final Factory mFactory;
private final ViewModelStore mViewModelStore;

先說說這兩個類的功能。

4.3 ViewModelProvider.Factory

Factory 接口定義了一個創建 ViewModel 的接口 create(),ViewModelProvider 在需要時調用該方法新建 ViewModel 對象。

public interface Factory {
    

Android 已經內置了2個 Factory 實現類,分別是:

AndroidViewModelFactory 實現類,可以創建 ViewModel 和 AndroidViewModel 子類對象。
NewInstanceFactory 類,只可以創建 ViewModel 子類對象。

它們的實現都是通過反射機制調用 ViewModel 子類的構造方法創建對象。

public static class NewInstanceFactory implements Factory {
    @Override
    public 

AndroidViewModelFactory 繼承 NewInstanceFactory 類,是個單例,支持創建 AndroidViewModel 子類對象。

public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {

    private static AndroidViewModelFactory sInstance;

    public static AndroidViewModelFactory getInstance(Application application) {
        if (sInstance == null) {
            sInstance = new AndroidViewModelFactory(application);
        }
        return sInstance;
    }

    private Application mApplication;

    public AndroidViewModelFactory(Application application) {
        mApplication = application;
    }

    @Override
    public 

4.4 ViewModelStore

ViewModelStore 類中維護一個 Map

public class ViewModelStore {
    private final HashMap<String, ViewModel> mMap = new HashMap<>();

    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = mMap.put(key, viewModel);
    }

    final ViewModel get(String key) {
        return mMap.get(key);
    }
}

4.5 ViewModelStoreOwner

ViewModelStore 是來自于 FragmentActivity 和 Fragment,它們實現了 ViewModelStoreOwner 接口,返回當前 UI 作用域里的 ViewModelStore 對象。

public interface ViewModelStoreOwner {
    ViewModelStore getViewModelStore();
}

在 Fragment 類中的實現如下:

public ViewModelStore getViewModelStore() {
    if (getContext() == null) {
        throw new IllegalStateException("Can't access ViewModels from detached fragment");
    }
    if (mViewModelStore == null) {
        mViewModelStore = new ViewModelStore();
    }
    return mViewModelStore;
}

在 FragmentActivity 類中的實現如下:

public ViewModelStore getViewModelStore() {
    if (getApplication() == null) {
        throw new IllegalStateException("Your activity is not yet attached to the "
                + "Application instance. You can't request ViewModel before onCreate call.");
    }
    if (mViewModelStore == null) {
        mViewModelStore = new ViewModelStore();
    }
    return mViewModelStore;
}

4.6 創建 ViewModelProvider

回到 of() 方法的實現

public static ViewModelProvider of(FragmentActivity activity, Factory factory) {
    Application application = checkApplication(activity);
    if (factory == null) {
        factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
    }
    return new ViewModelProvider(activity.getViewModelStore(), factory);
}

在創建 ViewModelProvider 對象時需要傳入 ViewModelStore 和 Factory 對象。若 factory 為 null,將使用 AndroidViewModelFactory 單例對象。

4.7 獲取 ViewModel 對象

調用 ViewModelProvider 對象的 get() 方法獲取 ViewModel 對象,如果在 ViewModelStore 里不存在,則使用 Factory 創建一個新的對象并存放到 ViewModelStore 里。

public <T extends ViewModel> T get(String key, Class<T> modelClass) {
    ViewModel viewModel = mViewModelStore.get(key);

    if (modelClass.isInstance(viewModel)) {
        return (T) viewModel;
    }

    viewModel = mFactory.create(modelClass);
    mViewModelStore.put(key, viewModel);

    return (T) viewModel;
}

5. Configuration Changes 存活原理

當 Activity 或 Fragment 被系統重建時,ViewModel 對象不會被銷毀,新的 Activity 或 Fragment 對象拿到的是同一個 ViewModel 對象。

在 FragmentActivity#onRetainNonConfigurationInstance() 方法中,會將 ViewModelStore 對象保留起來。

public final Object onRetainNonConfigurationInstance() {
    Object custom = onRetainCustomNonConfigurationInstance();

    FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();

    if (fragments == null && mViewModelStore == null && custom == null) {
        return null;
    }

    NonConfigurationInstances nci = new NonConfigurationInstances();
    nci.custom = custom;
    nci.viewModelStore = mViewModelStore;
    nci.fragments = fragments;
    return nci;
}

然后在 onCreate() 方法能獲取之前保留起來的 ViewModelStore 對象。

protected void onCreate(Bundle savedInstanceState) {
    mFragments.attachHost(null /*parent*/);
    super.onCreate(savedInstanceState);

    NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance();
    if (nc != null) {
        mViewModelStore = nc.viewModelStore;
    }
    // ...
}

那 Fragment 作用域里是如何實現的呢?在 FragmentActivity 的 onRetainNonConfigurationInstance() 方法中里有這樣一句代碼:

FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();

實現保留的機制是一樣的,只不過放在 FragmentManagerNonConfig 對象中。是在 FragmentManager#saveNonConfig() 方法中將 ViewModelStore 對象保存到 FragmentManagerNonConfig 里的。

void saveNonConfig() {
    ArrayList

該方法的調用順序是:FragmentActivity#onSaveInstanceState() -> FragmentManager#saveAllState() -> FragmentManager#saveNonConfig()。

6. 銷毀過程

在 FragmentActivity 類的 onDestory() 方法中。

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mViewModelStore != null && !isChangingConfigurations()) {
        mViewModelStore.clear();
    }
    mFragments.dispatchDestroy();
}

在 Fragment 類的 onDestory() 方法中。

public void onDestroy() {
    mCalled = true;
    FragmentActivity activity = getActivity();
    boolean isChangingConfigurations = activity != null && activity.isChangingConfigurations();
    if (mViewModelStore != null && !isChangingConfigurations) {
        mViewModelStore.clear();
    }
}

先判斷是否有發生 Configuration Changes,如果沒有則會調用 ViewModelStore 的 clear() 方法,再一一調用每一個 ViewModel 的 onCleared() 方法。

public final void clear() {
    for (ViewModel vm : mMap.values()) {
        vm.onCleared();
    }
    mMap.clear();
}

以上就是Android 中ViewModel組件如何使用,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女