Android MVVM学习之----ViewModel、ViewModelProvider、ComponentActivity的关系

目录

一、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层引用的。

猜你喜欢

转载自blog.csdn.net/mldxs/article/details/127172019