温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android 中ViewModel组件如何使用

发布时间:2021-08-12 11:33:55 阅读:243 作者: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<StringViewModel> 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() 方法中。

@Overrideprotected 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