编程语言
首页 > 编程语言> > JetPack框架组件3——ViewModel的使用和源码分析

JetPack框架组件3——ViewModel的使用和源码分析

作者:互联网

JetPack框架组件3——ViewModel的使用和源码分析

文章目录

一.ViewModel的使用和概述

1.使用场景

ViewModel是什么,ViewModel就是Activity/Fragment中的一个实体,是为了帮助Activity/fragmet承担业务逻辑,负责activity和model的沟通,承担资源的获取和释放工作,让activity和只承担ui变化的逻辑。

2.ViewModel生命周期

下图是ViewModel的生命周期
在这里插入图片描述
ViewModel的存在时间范围是和获取到ViewModel传递的Lifecycle相关联。也就是说,在Lifecycle彻底消失前。ViewModel将会一直存在于内存中。

所以基于ViewModel生命周期的特点,所以ViewModel具有下面的特点:

3.使用

定义ViewModel

class NameViewModel :ViewModel() {
    val currentName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

}

获取和使用ViewModel

class FirstFragment : Fragment() {

    override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false)
    }
	
	//	获取ViewModels
    private val model: NameViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val nameObserver = Observer<String> { newName ->
            textview_first.text = newName
        }
        model.currentName.observe(this, nameObserver)
        view.findViewById<Button>(R.id.button_first).setOnClickListener {
            val anotherName = "John Doe"
            //调用ViewModel
            model.currentName.setValue(anotherName)
        }
    }
}

4.ViewModel 关键类

ViewModel有两个关键的类,一个是ViewModelStore负责存储ViewModel,一个是ViewModelFactor负责生产ViewModel
所以我们看源码主要带着下面的问题看

二.ViewModelStore的获取

1.获取ViewModel的入口

ViewModel的入口方法:

    private val model: NameViewModel by viewModels()

进入看看实现:
FragmentViewModelLazy

@MainThread
inline fun <reified VM : ViewModel> Fragment.viewModels(
    noinline ownerProducer: () -> ViewModelStoreOwner = { this },
    //负责生产ViewModel,可以自定义实现
    noinline factoryProducer: (() -> Factory)? = null
    //ownerProducer().viewModelStore 负责存储ViewModel
) = createViewModelLazy(VM::class, { ownerProducer().viewModelStore }, factoryProducer)

2.ViewModelStore的定义

在看获取之前,我们先看看ViewModelStore的定义

public class ViewModelStore {
	//所以ViewModelStore本质就是一个hasMap
    private final HashMap<String, ViewModel> mMap = new HashMap<>();

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

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

    Set<String> keys() {
        return new HashSet<>(mMap.keySet());
    }
    public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.clear();
        }
        mMap.clear();
    }
}

由上面可以看出。ViewModelStore本质是一个封装的hasmap。

3.Activity中获取ViewModelStore

ownerProducer()的实现类在fragment中,我们往下看


public class ComponentActivity extends androidx.core.app.ComponentActivity {
    
    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) {
            NonConfigurationInstances nc =
                    (NonConfigurationInstances) getLastNonConfigurationInstance();
            if (nc != null) {
                // 从nc中恢复viewModelStore
                mViewModelStore = nc.viewModelStore;
            }
            //没有的话,重新创造一个
            if (mViewModelStore == null) {
                mViewModelStore = new ViewModelStore();
            }
        }
        return mViewModelStore;
    }
}

从源码里可以看出来,ViewModelStore优先从NonConfigurationInstances中获取,那么NonConfigurationInstances是什么呢,看下NonConfigurationInstances的定义

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
    static final class NonConfigurationInstances {
        Object custom;
        ViewModelStore viewModelStore;
    }
}

NonConfigurationInstances是一个包装类,简单的将viewModelStore和custom包装了一下

我们看一下LastNonConfigurationInstance是如何获取的

public class Activity extends ContextThemeWrapper {

    public Object getLastNonConfigurationInstance() {
        return mLastNonConfigurationInstances != null
                ? mLastNonConfigurationInstances.activity : null;
    }
}

总结:最终nc就是activity.mLastNonConfigurationInstances

4.Fragment中获取ViewModelStore

ownerProducer()的实现类在fragment中,我们继续往下看

public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
        ViewModelStoreOwner, SavedStateRegistryOwner {
        ....
    @NonNull
    @Override
    public ViewModelStore getViewModelStore() {
        if (mFragmentManager == null) {
            throw new IllegalStateException("Can't access ViewModels from detached fragment");
        }
        return mFragmentManager.getViewModelStore(this);
    }
    ...
}
final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 {
	...
    @NonNull
    ViewModelStore getViewModelStore(@NonNull Fragment f) {
    	//这里的mNonConfig也是ViewModel是实现类
        return mNonConfig.getViewModelStore(f);
    }
    ....
}

继续往下,如何从FragmentManagerViewModel中获取ViewModelStore

//这里也是ViewModel
class FragmentManagerViewModel extends ViewModel {
 private final HashMap<String, ViewModelStore> mViewModelStores = new HashMap<>();
    @NonNull
    ViewModelStore getViewModelStore(@NonNull Fragment f) {
    	//看看是否有缓存的viewModelStore
        ViewModelStore viewModelStore = mViewModelStores.get(f.mWho);
        if (viewModelStore == null) {
        	//没有的话重新创建一个
            viewModelStore = new ViewModelStore();
            mViewModelStores.put(f.mWho, viewModelStore);
        }
        return viewModelStore;
    }
}

再看看mNonConfig(FragmentManagerViewModel)是如何创建的

final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 {
	
    public void attachController(@NonNull FragmentHostCallback host,
            @NonNull FragmentContainer container, @Nullable final Fragment parent) {

        // Get the FragmentManagerViewModel
        if (parent != null) {
            mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
        //如果  host是ViewModelStoreOwner
        } else if (host instanceof ViewModelStoreOwner) {
            ViewModelStore viewModelStore = ((ViewModelStoreOwner) host).getViewModelStore();
            mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);
        } else {
            mNonConfig = new FragmentManagerViewModel(false);
        }
    }
    @NonNull
    FragmentManagerViewModel getChildNonConfig(@NonNull Fragment f) {
        return mNonConfig.getChildNonConfig(f);
    }
}
class FragmentManagerViewModel extends ViewModel {
  
    static FragmentManagerViewModel getInstance(ViewModelStore viewModelStore) {
        ViewModelProvider viewModelProvider = new ViewModelProvider(viewModelStore,
                FACTORY);
        return viewModelProvider.get(FragmentManagerViewModel.class);
    }
	//获取子Fragment的FragmentManagerViewModel
    FragmentManagerViewModel getChildNonConfig(@NonNull Fragment f) {
        FragmentManagerViewModel childNonConfig = mChildNonConfigs.get(f.mWho);
        if (childNonConfig == null) {
            childNonConfig = new FragmentManagerViewModel(mStateAutomaticallySaved);
            mChildNonConfigs.put(f.mWho, childNonConfig);
        }
        return childNonConfig;
    }
}

5.小结

三.ViewModelFactor的获取

1.获取ViewModelFactor的入口

上一节我们知道,获取ViewModel的入口,在下面
FragmentViewModelLazy

@MainThread
inline fun <reified VM : ViewModel> Fragment.viewModels(
    noinline ownerProducer: () -> ViewModelStoreOwner = { this },
    //负责生产ViewModel,可以自定义实现
    noinline factoryProducer: (() -> Factory)? = null
    //ownerProducer().viewModelStore 负责存储ViewModel
) = createViewModelLazy(VM::class, { ownerProducer().viewModelStore }, factoryProducer)

我们继续往下看
FragmentViewModelLazy

@MainThread
fun <VM : ViewModel> Fragment.createViewModelLazy(
    viewModelClass: KClass<VM>,
    storeProducer: () -> ViewModelStore,
    factoryProducer: (() -> Factory)? = null
): Lazy<VM> {
    val factoryPromise = factoryProducer ?: {
        val application = activity?.application ?: throw IllegalStateException(
            "ViewModel can be accessed only when Fragment is attached"
        )
        //获取默认的AndroidViewModelFactory
        AndroidViewModelFactory.getInstance(application)
    }
    return ViewModelLazy(viewModelClass, storeProducer, factoryPromise)
}

2.默认的ViewModelFactor - AndroidViewModelFactory

获取FragmentViewModelLazy

   public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {

        private static AndroidViewModelFactory sInstance;
		//单例
        @NonNull
        public static AndroidViewModelFactory getInstance(@NonNull Application application) {
            if (sInstance == null) {
                sInstance = new AndroidViewModelFactory(application);
            }
            return sInstance;
        }

        private Application mApplication;

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

        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
                //反射获取ViewModel
                try {
                    return modelClass.getConstructor(Application.class).newInstance(mApplication);
                } catch (NoSuchMethodException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                } catch (InstantiationException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                }
            }
            return super.create(modelClass);
        }
    }
}

3.小结

四.ViewModel的获取

上两节我们看了存储ViewModel的ViewModelStore的获取,和一个生产ViewModel的ViewModelFactor的获取。下面我们完整的梳理一下ViewModel的获取

1.入口

FragmentViewModelLazy

@MainThread
inline fun <reified VM : ViewModel> Fragment.viewModels(
    noinline ownerProducer: () -> ViewModelStoreOwner = { this },
    //负责生产ViewModel,可以自定义实现
    noinline factoryProducer: (() -> Factory)? = null
    //ownerProducer().viewModelStore 负责存储ViewModel
) = createViewModelLazy(VM::class, { ownerProducer().viewModelStore }, factoryProducer)

我们继续往下看
FragmentViewModelLazy

@MainThread
fun <VM : ViewModel> Fragment.createViewModelLazy(
    viewModelClass: KClass<VM>,
    storeProducer: () -> ViewModelStore,
    factoryProducer: (() -> Factory)? = null
): Lazy<VM> {
    val factoryPromise = factoryProducer ?: {
        val application = activity?.application ?: throw IllegalStateException(
            "ViewModel can be accessed only when Fragment is attached"
        )
        //获取默认的AndroidViewModelFactory
        AndroidViewModelFactory.getInstance(application)
    }
    return ViewModelLazy(viewModelClass, storeProducer, factoryPromise)
}

继续往下看

class ViewModelLazy<VM : ViewModel> (
    private val viewModelClass: KClass<VM>,
    private val storeProducer: () -> ViewModelStore,
    private val factoryProducer: () -> ViewModelProvider.Factory
) : Lazy<VM> {
    private var cached: VM? = null

    override val value: VM
        get() {
            //有缓存先获取缓存
            val viewModel = cached
            return if (viewModel == null) {
                val factory = factoryProducer()
                val store = storeProducer()
                //这里获取新的ViewModel
                ViewModelProvider(store, factory).get(viewModelClass.java).also {
                    cached = it
                }
            } else {
                viewModel
            }
        }

    override fun isInitialized() = cached != null
}

2.ViewModelProvider

在ViewModelProvider获取ViewModel

public class ViewModelProvider {
    @NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
        String canonicalName = modelClass.getCanonicalName();
        if (canonicalName == null) {
            throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
        }
        return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
    }
	
	@NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
        //优先从mViewModelStore获取ViewModel
        ViewModel viewModel = mViewModelStore.get(key);

        if (modelClass.isInstance(viewModel)) {
            //noinspection unchecked
            return (T) viewModel;
        } else {
            //noinspection StatementWithEmptyBody
            if (viewModel != null) {
                // TODO: log a warning.
            }
        }
		//如果没有就从mFactory中new一个
        if (mFactory instanceof KeyedFactory) {
            viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
        } else {
            viewModel = (mFactory).create(modelClass);
        }
        mViewModelStore.put(key, viewModel);
        //noinspection unchecked
        return (T) viewModel;
    }

}

3.小结

ViewModel的获取是在ViewModelProvider中获取的

五.ViewModel的恢复

上面我们完整的看完了一个viewModel的获取流程,但是我们最开始的疑问还是没有解决:

下面我们就来看这个问题
再这之前,先回顾一个之前看代码的细节:

Activity中获取ViewModelStore,它会优先在activity.mLastNonConfigurationInstances中获取
这里的mLastNonConfigurationInstances和我们要看的内容息息相关

1.保存

我们看一下,在发生设备状态改变时的回调。
ActivityThread.performDestroyActivity()

public final class ActivityThread extends ClientTransactionHandler {
    ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
            int configChanges, boolean getNonConfigInstance, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        ...
        if (r != null) {
            ....
            if (getNonConfigInstance) {
                try {
                	//保存lastNonConfigurationInstances变量
                    r.lastNonConfigurationInstances
                            = r.activity.retainNonConfigurationInstances();
                } catch (Exception e) {
                    if (!mInstrumentation.onException(r.activity, e)) {
                        throw new RuntimeException(
                                "Unable to retain activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
                    }
                }
            }
            ...
        return r;
    }
}

当设备状态发生改变时,Lifecycle状态改变为ON_DESTROY的会调

public class ComponentActivity extends androidx.core.app.ComponentActivity {
    public ComponentActivity() {
        getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    //	如果是发生了设置状态改变
                    if (!isChangingConfigurations()) {
                        getViewModelStore().clear();
                    }
                }
            }
        });
    }

}
  

2.恢复

当配置更改发生后,如何再次恢复
ActivityThread.performLaunchActivity

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        ...
        
        try {
            	...
            	//这里我们可以看到,将lastNonConfigurationInstances传入activity中
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken);

                ...
        } catch (SuperNotCalledException e) {
            ...

        } catch (Exception e) {
           ...
        }

        return activity;
    }

attach方法

    @UnsupportedAppUsage
    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
        attachBaseContext(context);

	      .....
	     //完成赋值
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
	    ....
    }

3.小结

ViewModel的恢复其实本质就是在配置信息发生改变后,在activity销毁前,将其保存,然后再activity重建后,将其恢复。

4.其他

资源不足,或者后台进程关闭后所导致的activity被回收,viewModel是否可以将数据恢复
答:不可以,但是可以支持

使用SavedStateHandle

六.ViewModel与SavedStateHandle

1.SavedStateHandle的介绍

我们知道如果资源不足,或者后台进程关闭后所导致的activity被回收,viewModel是不可以将数据恢复。如果此时想让数据恢复,我们就要引入SavedStateHandle

在这里插入图片描述
所以onSaveInstanceState方法能保存的数据的场景:

onSaveInstanceState特点:
onSaveInstanceState方法只能保存少量简单的数据,大量和复杂数据最后不要放在onSaveInstanceState方法保存。因为onSaveInstanceState方法是通过Bundle保存数据,如果数据的量太大或者太复杂,会阻塞UI线程,从而影响Activity生命周期的执行。

2.SavedStateHandle的使用

SavedStateHandle的使用比较简单
定义ViewModerl

class NameWithSaveViewModel(private  val saveStateHandle: SavedStateHandle) :ViewModel() {
    // 需要在资源限制导致重建的场景下保存的数据
    // 用LiveData暴露,不能让外部直接通过LiveData去修改内部的值
    val mAgeLiveData: LiveData<Int> = saveStateHandle.getLiveData(KEY_AGE)
    
    fun setAge(age: Int) {
        saveStateHandle.set(KEY_AGE, age)
    }

    companion object {
        const val KEY_AGE = "key_age";
    }

}

创建ViewModel对下,使用VeiwModel

class FirstFragment : Fragment() {

    override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false)
    }
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
		
		//创建Viewmodel
        val viewModel = ViewModelProvider(
            this,
            SavedStateViewModelFactory(activity?.application, this)
        )[NameWithSaveViewModel::class.java]
      
        view.findViewById<Button>(R.id.button_first).setOnClickListener {
            //保存数据
            viewModel.setAge(1)
        }
    }
}

3.SavedStateHandle相关类

和SavedStateHandle 相关有四个类,SavedStateRegistryOwner,SavedStateRegistryController,SavedStateRegistry,SavedStateProvider。

我们分别看看这四个类的作用

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ViewModelStoreOwner,
        SavedStateRegistryOwner, 
        OnBackPressedDispatcherOwner {
	
	private final SavedStateRegistryController mSavedStateRegistryController =
            SavedStateRegistryController.create(this);
    // ······
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSavedStateRegistryController.performRestore(savedInstanceState);
        // ······
    }
 
    @CallSuper
    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        // ······
        mSavedStateRegistryController.performSave(outState);
    }
    // ······

	
}

从上面的代码我们可以看出来:SavedStateRegistryController主要分为两个过程:

4.SavedStateHandle保存数据

入口代码:

mSavedStateRegistryController.performSave(outState);

SavedStateRegistryController中

public final class SavedStateRegistryController {
    private final SavedStateRegistryOwner mOwner;
    private final SavedStateRegistry mRegistry;
    @MainThread
    public void performSave(@NonNull Bundle outBundle) {
        mRegistry.performSave(outBundle);
    }
}

在SavedStateRegistr中

public final class SavedStateRegistry {
    @MainThread
    void performSave(@NonNull Bundle outBundle) {
        Bundle components = new Bundle();
        if (mRestoredState != null) {
            components.putAll(mRestoredState);
        }
        //SavedStateProvider
        for (Iterator<Map.Entry<String, SavedStateProvider>> it =
                mComponents.iteratorWithAdditions(); it.hasNext(); ) {
            Map.Entry<String, SavedStateProvider> entry1 = it.next();
            //saveState需要保存的数据
            components.putBundle(entry1.getKey(), entry1.getValue().saveState());
        }
        outBundle.putBundle(SAVED_COMPONENTS_KEY, components);
    }
}

SavedStateProvider定义

    public interface SavedStateProvider {
        @NonNull
        Bundle saveState();
    }

5.SavedStateHandle恢复数据

入口代码

     mSavedStateRegistryController.performRestore(savedInstanceState);

SavedStateRegistryController中

public final class SavedStateRegistryController {
    private final SavedStateRegistryOwner mOwner;
    private final SavedStateRegistry mRegistry;
    @MainThread
    public void performRestore(@Nullable Bundle savedState) {
        Lifecycle lifecycle = mOwner.getLifecycle();
        if (lifecycle.getCurrentState() != Lifecycle.State.INITIALIZED) {
            throw new IllegalStateException("Restarter must be created only during "
                    + "owner's initialization stage");
        }
        lifecycle.addObserver(new Recreator(mOwner));
        mRegistry.performRestore(lifecycle, savedState);
    }

}

在SavedStateRegistr中

public final class SavedStateRegistry {
    @MainThread
    void performRestore(@NonNull Lifecycle lifecycle, @Nullable Bundle savedState) {
        if (mRestored) {
            throw new IllegalStateException("SavedStateRegistry was already restored.");
        }
        if (savedState != null) {
        	//恢复数据
            mRestoredState = savedState.getBundle(SAVED_COMPONENTS_KEY);
        }

        lifecycle.addObserver(new GenericLifecycleObserver() {
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_START) {
                    mAllowingSavingState = true;
                } else if (event == Lifecycle.Event.ON_STOP) {
                    mAllowingSavingState = false;
                }
            }
        });

        mRestored = true;
    }
}

目前是将数据保持在mRestoredState,但并没有给ViewModel。什么时候赋值给ViewMoedl,我们换个角度看看,从VIewModel的重新创建看起。在SavedStateHandle场景中,ViewModel的工厂类是SavedStateViewModelFactory。我们看看此时ViewModel的创建

public final class SavedStateViewModelFactory extends ViewModelProvider.KeyedFactory {

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {
        boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
        Constructor<T> constructor;
        //获取viewmodel的modelClass
        if (isAndroidViewModel && mApplication != null) {
            constructor = findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE);
        } else {
            constructor = findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE);
        }
		...
		//创建controller
        SavedStateHandleController controller = SavedStateHandleController.create(
                mSavedStateRegistry, mLifecycle, key, mDefaultArgs);
        try {
            T viewmodel;
            if (isAndroidViewModel && mApplication != null) {
      			//创建viewmodel对象
                viewmodel = constructor.newInstance(mApplication, controller.getHandle());
            } else {
                viewmodel = constructor.newInstance(controller.getHandle());
            }
            viewmodel.setTagIfAbsent(TAG_SAVED_STATE_HANDLE_CONTROLLER, controller);
            return viewmodel;
        } catch (IllegalAccessException e) {
         	...
        }
    }
 }

我们看看SavedStateHandleController中做了什么

final class SavedStateHandleController implements LifecycleEventObserver {
    static SavedStateHandleController create(SavedStateRegistry registry, Lifecycle lifecycle,
            String key, Bundle defaultArgs) {
        //获取之前保存的Bundle    
        Bundle restoredState = registry.consumeRestoredStateForKey(key);
        SavedStateHandle handle = SavedStateHandle.createHandle(restoredState, defaultArgs);
        SavedStateHandleController controller = new SavedStateHandleController(key, handle);
        //将SavedStateHandle的SavedStateProvider注册到SavedStateRegistry
        controller.attachToLifecycle(registry, lifecycle);
        tryToAddRecreator(registry, lifecycle);
        return controller;
    }

 }

在SavedStateRegistr中

public final class SavedStateRegistry {
    public Bundle consumeRestoredStateForKey(@NonNull String key) {
        if (!mRestored) {
            throw new IllegalStateException("You can consumeRestoredStateForKey "
                    + "only after super.onCreate of corresponding component");
        }
        if (mRestoredState != null) {
            Bundle result = mRestoredState.getBundle(key);
            mRestoredState.remove(key);
            if (mRestoredState.isEmpty()) {
                mRestoredState = null;
            }
            //返回恢复的Bundle
            return result;
        }
        return null;
    }
}

小结:
1.在activityd的onCreate 通过SavedStateHandleController恢复之前保持的数据
2.在SavedStateHandle场景中,ViewModel的工厂类是SavedStateViewModelFactory,此时ViewModel通过SavedStateViewModelFactory创建
3.在ViewModel的create中通过SavedStateHandleController获得之前保存的数据
4.ViewModel根据之前获得的数据,通过反射方式创建一个新的ViewModel

七.参考资料

ViewModel源码,学起来!

JetPack之ViewModel源码解析

官方文档

标签:ViewModelStore,NonNull,JetPack,ViewModel,class,获取,源码,public
来源: https://blog.csdn.net/qq_38499859/article/details/118655986