Android MVVM学习之----ViewModelViewModelProviderComponentActivity的关系

Posted mldxs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android MVVM学习之----ViewModelViewModelProviderComponentActivity的关系相关的知识,希望对你有一定的参考价值。

目录

一、ViewModel的出生

二、ViewModel的结束

三、总结:


我们通过ViewModel的生命周期来作为主线,讲解ViewModel、ViewModelProvider、ComponentActivity三者的关系。

一、ViewModel的出生

创建ViewModel,通过调用ViewModelProvider的get方法。

mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
//ViewModelProvider.class
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) 
    this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
            ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
            : NewInstanceFactory.getInstance());

public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) 
    mFactory = factory;
    mViewModelStore = store;

public ViewModelStore getViewModelStore() 
    ...
    ensureViewModelStore();
    return mViewModelStore;

void ensureViewModelStore() 
    if (mViewModelStore == null) 
        NonConfigurationInstances nc =
                (NonConfigurationInstances) getLastNonConfigurationInstance();
        if (nc != null) 
            // Restore the ViewModelStore from NonConfigurationInstances
            mViewModelStore = nc.viewModelStore;
        
        if (mViewModelStore == null) 
            mViewModelStore = new ViewModelStore();
        
    

获取owner的ViewModelStore(AppCompatActivity 兼容 -> FragmentActiity -> ComponentActivity 组件 ComponentActivty实现了ViewModelStoreOwner和LifecycleOwner接口)

ViewModelStore内部有一个HashMap用来存储ViewModel

所以ViewModelStore里的mViewModelStore即是Activity,ViewModelProvider持有mViewModelStore的引用,ViewModelProvider内部持有mViewModelStore引用

//ViewModelProvider.class
public <T extends ViewModel> T get(@NonNull Class<T> modelClass) 
    ...
    return get(DEFAULT_KEY + ":" + modelClass.getCanonicalName(), modelClass);


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

    if (modelClass.isInstance(viewModel)) 
        if (mFactory instanceof OnRequeryFactory) 
            ((OnRequeryFactory) mFactory).onRequery(viewModel);
        
        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);
    return (T) viewModel;


public <T extends ViewModel> T create(@NonNull Class<T> modelClass) 
    return modelClass.newInstance();
    ...

get方法会创建ViewModel对象,使用Factory工厂来创建 , 工厂通过反射来创建ViewModel。

而由于我们是使用ViewModelProvider(ViewModelStoreOwner))来创建的ViewModelProvider,所以这里使用的ViewModelProvider.Factory其实是ComponentActivity,因为ComponentActivity实现了HasDefaultViewModelProviderFactory接口。

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
...
        HasDefaultViewModelProviderFactory
    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() 
        ...
        mDefaultFactory = new SavedStateViewModelFactory(
                getApplication(),
                this,
                getIntent() != null ? getIntent().getExtras() : null);
    
        return mDefaultFactory;
                                             

到此,我们创建的ViewModel实际保存在了mViewModelStore的HashMap里,而mViewModelStore是属于Activity的成员变量。

二、ViewModel的结束

开始:ViewModel的创建上面已经讲的很多了,生命的开始是从我们创建ViewModel开始

结束:而生命的结束就不是由我们自己控制的了,因为我们的ViewModel是存储在Activity的ViewModelStore里,所以生命的结束也是由Activity来处理的。

public ComponentActivity() 
    Lifecycle lifecycle = getLifecycle();
    ...
    getLifecycle().addObserver(new LifecycleEventObserver() 
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) 
            if (event == Lifecycle.Event.ON_DESTROY) 
                ...
                getViewModelStore().clear();
            
        
    );
    ...

在创建ComponentActivity的时候,我们注册了Activity的Lifecycle监听,当Activity.onDestory的时候会自动清空所有的ViewModel,并且会给ViewModel一个onCleared回调,告诉它已经没人引用它了。并对

ViewModel里的mBagOfTags挨个调用close方法

//ViewModel.class
protected void onCleared() 


@MainThread
final void clear() 
    mCleared = true;
    if (mBagOfTags != null) 
        synchronized (mBagOfTags) 
            for (Object value : mBagOfTags.values()) 
                // see comment for the similar call in setTagIfAbsent
                closeWithRuntimeException(value);
            
        
    
    onCleared();

综上所述,ViewModel是有生命周期的,生命的结束由Activity控制

三、总结:

1、ViewModelProvider其实只是一个中介:

ViewModel的创建,工厂ViewModelProvider.Factory实际是由ComponentActivity持有。

ViewModel的存储,ViewModelStore来负责并且由ComponentActivity持有。

ViewModel的销毁,还是由ComponentActivity来负责。

2、ViewModel就是MVVM中的核心VM,由ComponentActivity来负责生命周期和存储。

3、ComponentActivity就是ViewModel的全权大管家。

4、MVVM中的view层是持有viewmodel层引用的。

以上是关于Android MVVM学习之----ViewModelViewModelProviderComponentActivity的关系的主要内容,如果未能解决你的问题,请参考以下文章

前端学习之JavaScript的框架

MVVM

Android学习之网上商城(上)

Android学习之布局

Android学习之Drawable

Android学习之AsyncTask