看完这篇文章,LiveData的用法竟然还可以这样用?

简介: livedata

本文主要内容:

  1. 作用介绍
  2. 核心类介绍
  3. 基本使用
  4. 源码分析

    -- 横竖屏切换恢复
    -- 后台销毁恢复
    
    • *

ViewModel的主要工作:

本身主要是一个数据维护工具
将数据维护的工作从Activity上剥离,提供一个储存数据环境,自身机制可以解决开发中,数据受Activity生命周期影响产生数据丢失的问题 (主要为横竖屏切换以及在后台被销毁)。
通常结合LiveData使用。

作为一个纯数据维护工具,可以加入到MVP架构中负责数据保存。
而官方推选作为AAC架构MVVM中的VM层。

    • *

ViewModel的主要类:

  • ViewModel (下称VM)
    数据储存类,架构的核心类。
    使用时,直接继承该类,根据需求选择重写onCleared()方法。
    如需在Activity被系统销毁后依然保存数据,定义一个参数为(SavedStateHandle)的构造方法,并将数据保存SavedStateHandle中。
    实际上通过SavedInstanceState存取
  • AndroidViewModel
    VM子类,维护了Application的引用,由架构中的SavedStateViewModelFactory创建时传入。
    同样,需要接收SavedStateHandle时,需要定义参数为 (Application, SavedStateHandle)的构造方法。
  • ViewModelStore
    用于保存VM,内部维护了一个用于储存VMHashMap
    一般情况下,直接使用本类创建实例。
  • ViewModelStoreOwner
    接口,实现该接口的类,表示自身能够向外提供VM
    androidx 的AppCompatActivity/Fragment实现了该接口。
  • ViewModelProvider
    VM的提供者,获取VM的基本入口。
    实际依赖ViewModelStore存取VMFactory生成/恢复VM
  • Factory
    接口,实现该接口的类主要用于创建VM实例。
    不建议直接实现该接口,除非你清楚框架内容和自己的需求。
    一般情况下,如果无需SavedStateHandle机制,可以使用AndroidViewModelFactory
    否则应该使用或继承SavedStateViewModelFactory
    • *

ViewModel的基本使用:

  • 一般使用:
// VM
class ViewModelA : ViewModel()
// AVM
class ViewModelB(app: Application) : AndroidViewModel(app)

// Activity/Fragment .onCreate中
override fun onCreate() {
  ...
  val provider = ViewModelProvider(this)
  val vmA = provider.get(ViewModelA::class.java)
  val vmB = provider.get(ViewModelB::class.java)
  ...
}
  • 接受 SavedStateHandle
// VM
class ViewModelC(
        val handle: SavedStateHandle
) : ViewModel()

// AVM
class ViewModelD(
        app: Application, 
        val handle: SavedStateHandle
) : AndroidViewModel(app)
  • 跨 Fragment 共享数据

    Fragment中直接以Activity作为ViewModel的Key
    
...
val provider = ViewModelProvider(requireActivity())
val vmA = provider.get(ViewModelA::class.java)
  • 通过 Application 创建全局共享的 VM
class App : Application(), ViewModelStoreOwner {
    private lateinit var mAppViewModelStore: ViewModelStore
    private lateinit var mFactory: ViewModelProvider.Factory

    override fun onCreate() {
        super.onCreate()
        mAppViewModelStore = ViewModelStore()
        mFactory = ViewModelProvider
                      .AndroidViewModelFactory
                      .getInstance(this)
    }

    override fun getViewModelStore(): ViewModelStore {
        return mAppViewModelStore
    }

    private fun getAppFactory(): ViewModelProvider.Factory {
        return mFactory
    }

    fun getAppViewModelProvider(activity: Activity): ViewModelProvider {
        val app = checkApplication(activity) as App
        return ViewModelProvider(app, app.getAppFactory())
    }

    fun getAppViewModelProvider(fragment: Fragment): ViewModelProvider {
        return getAppViewModelProvider(fragment.requireActivity())
    }

    private fun checkApplication(activity: Activity): Application {
        return activity.application
                ?: throw IllegalStateException(
                      "Your activity is not yet attached to the Application instance." + 
                      "You can't request ViewModel before onCreate call.")
    }
}
    • *

ViewModel的关键源码分析:

以下源码分析将会去除非相关代码以简化

  • ViewModelProvider 实现相关:

前面提到,ViewModelProvider的工作完全依赖传入的ViewModelStoreFactory,可以直接从构造方法得知:

ViewModelProvider.java
----------------------

private final Factory mFactory;
private final ViewModelStore mViewModelStore;

public ViewModelProvider(ViewModelStoreOwner owner) {
  this(owner.getViewModelStore(), 
        owner instanceof HasDefaultViewModelProviderFactory
        ? ((HasDefaultViewModelProviderFactory) owner)
            .getDefaultViewModelProviderFactory()
        : NewInstanceFactory.getInstance());
}

public ViewModelProvider(ViewModelStoreOwner owner, Factory factory) {
    this(owner.getViewModelStore(), factory);
}

public ViewModelProvider(ViewModelStore store, Factory factory) {
    mFactory = factory;
    mViewModelStore = store;
}

// 简单的反射创建实例的工厂
public static class NewInstanceFactory implements Factory {
    public <T extends ViewModel> T create(Class<T> modelClass) {
        return modelClass.newInstance()
    }
}

androidx.activity.ComponentActivityandroidx.fragment.app.Fragment都实现了ViewModelStoreOwnerHasDefaultViewModelProviderFactory接口。

public class AppCompatActivity extends FragmentActivity...{}
public class FragmentActivity extends ComponentActivity...{}

public class ComponentActivity extends ... implements
        ViewModelStoreOwner,
        HasDefaultViewModelProviderFactory,
        SavedStateRegistryOwner ... {}

public class Fragment implements 
        ViewModelStoreOwner, 
        HasDefaultViewModelProviderFactory, 
        SavedStateRegistryOwner ... {}

ViewModelProviderget()方法中返回VM实例,其中mFactorySavedStateViewModelFactory

ViewModelProvider.java
----------------------

private static final String DEFAULT_KEY 
      = "androidx.lifecycle.ViewModelProvider.DefaultKey";

public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
    String canonicalName = modelClass.getCanonicalName();
    return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
}

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

    // 一个确保机制
    if (modelClass.isInstance(viewModel)) {
        if (mFactory instanceof OnRequeryFactory) {
            ((OnRequeryFactory) mFactory).onRequery(viewModel);
        }
        return (T) viewModel;
    }

    // 正常以及基本的逻辑
    if (mFactory instanceof KeyedFactory) {
        viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
    } else {
        viewModel = (mFactory).create(modelClass);
    }

    mViewModelStore.put(key, viewModel);
    return (T) viewModel;
}

SavedStateViewModelFactory在后面解析。

    • *
  • ViewModel 的屏幕横竖屏切换恢复机制:

前面说到,创建VM是通过ViewModelProvider实现的,而ViewModelProvider又是依赖ViewModelStore进行VM的保存。
当使用ComponentActivity/Fragment作为ViewModelProvider的初始化参数时,实际VM的储存容器是参数提供的。

  1. ComponentActivity 实现:

从源码中,可以看出横竖屏切换是直接通过NonConfigurationInstances进行恢复的。

ComponentActivity包含一个NonConfigurationInstances类,其中持有ViewModelStore的引用:

ComponentActivity.java
----------------------

static final class NonConfigurationInstances {
    Object custom;
    ViewModelStore viewModelStore;
}

保存ViewModelStore
通过onRetainNonConfigurationInstance()在横竖屏切换中保存ViewModelStore

ComponentActivity.java
----------------------

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

    // 从上一个 NonConfigurationInstances 中恢复 ViewModelStore
    ViewModelStore viewModelStore = mViewModelStore;
    if (viewModelStore == null) {
        NonConfigurationInstances nc = 
                (NonConfigurationInstances) getLastNonConfigurationInstance();

        if (nc != null) {
            viewModelStore = nc.viewModelStore;
        }
    }

    if (viewModelStore == null && custom == null) {
        return null;
    }

    // 保存当前 ViewModelStore
    NonConfigurationInstances nci = new NonConfigurationInstances();
    nci.custom = custom;
    nci.viewModelStore = viewModelStore;
    return nci;
}

在使用时尝试通过getLastNonConfigurationInstance()恢复ViewModelStore

ComponentActivity.java
----------------------

public ViewModelStore getViewModelStore() {
    if (mViewModelStore == null) {
        NonConfigurationInstances nc = 
                (NonConfigurationInstances) getLastNonConfigurationInstance();

        if (nc != null) {
            // 通过 NonConfigurationInstances 对象直接恢复 ViewModelStore
            mViewModelStore = nc.viewModelStore;
        }
        if (mViewModelStore == null) {
            mViewModelStore = new ViewModelStore();
        }
    }
    return mViewModelStore;
}
  1. Fragment 实现:

要看懂该部分源码,需要对FragmentManager有基础了解,参考:深入理解FragmentManager

FragmentViewModelStoreFragmentManager维护的FragmentManagerViewModel管理。

  • 注意这里使用了一个VM来维护一个ViewModelStore
Fragment.java
-------------

public ViewModelStore getViewModelStore() {
    return mFragmentManager.getViewModelStore(this);
}

FragmentManager.java
--------------------

private FragmentManagerViewModel mNonConfig;

ViewModelStore getViewModelStore(Fragment f) {
    return mNonConfig.getViewModelStore(f);
}

处理FragmentManagerViewModel的实例化:

FragmentManager.java
--------------------

void attachController(FragmentHostCallback<?> host, 
                      FragmentContainer container,
                      final Fragment parent) {
    mHost = host;
    mParent = parent;

    if (parent != null) {
        // 从父类的FM中获取
        mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
    } else if (host instanceof ViewModelStoreOwner) {
        // 假如 host 对象是实现了 ViewModelStoreOwner
        // 则使用这个ViewModelStoreOwner的viewModelStore创建一个 FragmentManagerViewModel
        ViewModelStore viewModelStore = 
                ((ViewModelStoreOwner) host).getViewModelStore();
        mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);
    } else {
        // 生成一个不支持自动保存ViewModel的 FragmentManagerViewModel
        mNonConfig = new FragmentManagerViewModel(false);
    }
}

但从源码注释可以了解到,第三种情况已废弃,理想情况下并不支持。

所以基本上,出现的应该为第一、第二种情况。

host对象实际是实现的ViewModelStoreOwner接口的FragmentActivity$HostCallbacks

FragmentActivity.java
---------------------

class HostCallbacks 
            extends FragmentHostCallback<FragmentActivity> 
            implements ViewModelStoreOwner ... {...}

第二种情况,attachController()传入参数为null,可以理解为直接附着在FragmentActivity上的Fragment:

FragmentActivity.java
---------------------

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

FragmentController.java
-----------------------

public void attachHost(Fragment parent) {
    mHost.mFragmentManager.attachController(mHost, mHost, parent);
}

而第一种情况,attachController()传入参数为Fragment,在FragmentperformAttach()中调用:

Fragment.java
-------------

void performAttach() {
    mChildFragmentManager.attachController(mHost, new FragmentContainer(), this)
}

...
解决了FragmentManagerViewModel的来源,下面看看它的作用。
上文提到,FragmentManagerViewModel是一个VM,实际上可以联想到可能是通过ActivityViewModelStore,使用相同的NonConfigurationInstances机制实现的恢复。

先看第二种情况:

FragmentManager.java
--------------------

ViewModelStore viewModelStore = ((ViewModelStoreOwner) host).getViewModelStore();
mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);

其中的hostFragmentActivity$HostCallbacks,而getViewModelStore()返回的实际上是FragmentActivityViewModelStore

FragmentActivity$HostCallbacks.java
-----------------------------------

public ViewModelStore getViewModelStore() {
    return FragmentActivity.this.getViewModelStore();
}

FragmentManagerViewModel.getInstance()内部实际上是通过ViewModelProvider返回一个本类VM实例:

FragmentManagerViewModel .java
------------------------------

static FragmentManagerViewModel getInstance(ViewModelStore viewModelStore) {
    ViewModelProvider viewModelProvider = 
                new ViewModelProvider(viewModelStore, FACTORY);
    return viewModelProvider.get(FragmentManagerViewModel.class);
}

由于VM在创建时,会被储存到对应的ViewModelStore,所以该VM会存放到FragmentActivityViewModelStore中。

第一种情况:
实际上是顶级FragmentManagerFragmentManagerViewModel中,维护一个子级的FragmentManagerViewModel仓库,然后通过顶级FragmentManagerViewModel直接维护所有子级FragmentManagerViewModel

FragmentManagerViewModel .java
------------------------------

private final HashMap<String, FragmentManagerViewModel> mChildNonConfigs = new HashMap<>();

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;
}

...
从以上源码中可以看出,Fragment的横竖屏切换恢复机制实际上是:

  • 通过一个持有自身ViewModelStore引用的VM,依附到ActivityViewModelStore中,通过Activity的机制进行恢复。

其实这里引申一点的是,源码中提及到,NonConfigurationInstances机制有可能在调用getLastNonConfigurationInstance时返回null,如需确保横竖屏切换时的数据保存,可以使用FragmentonSaveInstanceState(true),以Fragment作为保存数据的容器。

而事实上,在旧版的ViewModel中,确实是通过FragmentonSaveInstanceState(true)进行的。

    • *
  • ViewModel 的后台销毁恢复机制:

前文提到,SavedStateViewModelFactory是实现该机制的一部分,由SavedStateViewModelFactory生成的VM才具有在后台销毁前后通过SavedStateHandle存取数据的特性。

    • *

先看SavedStateViewModelFactory的构造方法:

SavedStateViewModelFactory.java
-------------------------------

public SavedStateViewModelFactory(Application application,
                                  SavedStateRegistryOwner owner,
                                  Bundle defaultArgs) {

    mSavedStateRegistry = owner.getSavedStateRegistry();
    mLifecycle = owner.getLifecycle();
    mDefaultArgs = defaultArgs;
    mApplication = application;
    mFactory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}

SavedStateViewModelFactoryComponentActivity中实例化传入的参数为:

ComponentActivity.java
----------------------

mDefaultFactory = new SavedStateViewModelFactory(
                            getApplication(), 
                            this, 
                            getIntent() != null ? getIntent().getExtras() : null);

ComponentActivity实现了SavedStateRegistryOwner接口,该接口的实现类可以提供SavedStateRegistry实例。

    • *

SavedStateRegistry即是流程的关键对象之一。
这里涉及到androidx提供的一个新的组件androidx.savedstate:"该组件允许以插件方式,将组件添加到SaveInstanceState过程中"。

个人理解:
这是一套针对SavedState操作Bundle的封装工具,但仅适用于系统实现。
因为流程繁琐,系统源码在实现的过程中还包含了自动重建,自动还原数据,生命周期确保等一系列操作。
而且当你实现关键的SavedStateProvider接口时,同样要编写Bundle,这和传统的onSaveInstanceState()区别不大。
因为系统实现了对VM提供的存取操作,建议直接使用VM,或者直接在onSaveInstanceState()对数据进行操作。

image

我后面有空会另行写一篇文章去讨论系统对该组件的实现。

    • *

ComponentActivity实例化时,创建成员SavedStateRegistryController,后者实例化时,创建成员SavedStateRegistry

ComponentActivity.java
----------------------

private final SavedStateRegistryController mSavedStateRegistryController =
                SavedStateRegistryController.create(this);

SavedStateRegistryController.java
---------------------------------

public static SavedStateRegistryController create(SavedStateRegistryOwner owner) {
    return new SavedStateRegistryController(owner);
}

private SavedStateRegistryController(SavedStateRegistryOwner owner) {
    mOwner = owner;
    mRegistry = new SavedStateRegistry();
}

ComponentActivityonSaveInstanceState()中调用SavedStateRegistryController.performSave(),内部实际调用SavedStateRegistry.performSave()

ComponentActivity.java
----------------------

protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mSavedStateRegistryController.performSave(outState);
}

SavedStateRegistryController.java
---------------------------------

public void performSave(Bundle outBundle) {
    mRegistry.performSave(outBundle);
}

SavedStateRegistry会把所有注册到自身的SavedStateProvider,通过saveState()提取数据,并保存到一个Bundle中:

SavedStateRegistry.java
-----------------------

void performSave(@NonNull Bundle outBundle) {
    Bundle components = new Bundle();
    for (Iterator<Map.Entry<String, SavedStateProvider>> it = 
                    mComponents.iteratorWithAdditions(); it.hasNext(); ) {

        Map.Entry<String, SavedStateProvider> entry1 = it.next();
        components.putBundle(entry1.getKey(), entry1.getValue().saveState());
    }
    outBundle.putBundle(SAVED_COMPONENTS_KEY, components);
}

至此,说明数据保存的发起,最终通知到SavedStateRegistry

    • *

先看SavedStateProvider接口:

注册到SavedStateRegistry中实现类,会在SavedStateRegistry保存过程将会调用saveState()获取数据。
而稍后(在恢复数据时),将会通过SavedStateRegistry.consumeRestoredStateForKey()取出保存的数据。

image

SavedStateProvider通过SavedStateRegistry.registerSavedStateProvider()注册到SavedStateRegistry

SavedStateRegistry.java
-----------------------

public void registerSavedStateProvider(String key, SavedStateProvider provider) {
    SavedStateProvider previous = mComponents.putIfAbsent(key, provider);
    if (previous != null) {
        throw new IllegalArgumentException(
                "SavedStateProvider with the given key is already registered");
    }
}

到此,说明储存数据的提供者,是注册到SavedStateRegistry中的SavedStateProvider

    • *

前文提及,VM的存取核心是SavedStateHandle,那么说明SavedStateProviderSavedStateHandle存在必然的关联。
实际上,SavedStateHandle实例中,维护一个SavedStateProvider匿名内部类实例,而SavedStateHandle的读写和SavedStateProvider实例的数据读取操作,都是对实际数据容器mRegular读写。

先看SavedStateHandle

  • 前文提到,最终该机制的实现,实际为SaveInstanceState机制,则反映VM并不会对数据进行自动存取。

    事实上`VM`确实需要手动将后台销毁前保存的数据放到`SaveInstanceState`中,`SavedStateHandle`确实是这么用的,所以提供了一系列的`get`/`set`操作,而最终还要编写`SavedStateProvider`的`Bundle`转换操作。
    
  • 同时可以看出,SavedStateHandle提供了对LiveData的存取支持。

    `SavedStateHandle`对`LiveData`的支持,来自对`LiveData`的内部的静态包装类`SavingStateLiveData`。
    `SavingStateLiveData`包装了`setValue()`,传入的参数会被优先储存到`mRegular`中。
    

用于提取数据的SavedStateProvider

需要编写SavedStateProvider数据的Bundle转换操作。
所以如无必要,无需自定义该组件,建议在onSaveInstanceState()中直接操作。

SavedStateHandle.java
---------------------

// 最终的数据容器主体
// initialState为构造时参入的上次SavedInstanceState产生的旧数据
// 既 SavedStateHandle.createHandle 时传入的参数,下面会说明
final Map<String, Object> mRegular = new HashMap<>(initialState);

// SavedStateProvider 对数据主体 mRegular 进行处理并生成一个Bundle
private final SavedStateProvider mSavedStateProvider = new SavedStateProvider() {
        public Bundle saveState() {
            Set<String> keySet = mRegular.keySet();
            ArrayList keys = new ArrayList(keySet.size());
            ArrayList value = new ArrayList(keys.size());
            for (String key : keySet) {
                keys.add(key);
                value.add(mRegular.get(key));
            }
            Bundle res = new Bundle();
            // "parcelable" arraylists - lol
            res.putParcelableArrayList("keys", keys);
            res.putParcelableArrayList("values", value);
            return res;
        }
};

至此,SavedStateHandleSavedStateProvider实现关联。

    • *

前文提及,SavedStateProvider通过SavedStateRegistry.registerSavedStateProvider()注册到SavedStateRegistry

而该方法的调用,则是通过SavedStateHandleController进行的。
SavedStateHandleController的实例化则是通过SavedStateViewModelFactory进行的,最终回到了SavedStateViewModelFactory

先看SavedStateViewModelFactory

通过调用SavedStateHandleController.create()返回SavedStateHandleController实例。
同时,VM在创建时,传入了SavedStateHandleControllerSavedStateHandle实例作为参数,即VMSavedStateHandle进行了绑定。

SavedStateViewModelFactory.java
-------------------------------

public <T extends ViewModel> T create(String key, Class<T> modelClass) {

    // 判断是否是AVM
    boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
    Constructor<T> constructor;
    if (isAndroidViewModel) {
        constructor = findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE);
    } else {
        constructor = findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE);
    }

    // 如果不需要SavedStateHandle,则直接创建一个普通的VM/AVM
    if (constructor == null) {
        return mFactory.create(modelClass);
    }

    // 创建了 SavedStateHandleController 
    SavedStateHandleController controller = SavedStateHandleController.create(
                                mSavedStateRegistry, mLifecycle, key, mDefaultArgs);

    // VM 在创建的时候持有了SavedStateHandleController内维护的SavedStateHandle对象
    try {
        T viewmodel;
        if (isAndroidViewModel) {
            viewmodel = constructor.newInstance(mApplication, controller.getHandle());
        } else {
            viewmodel = constructor.newInstance(controller.getHandle());
        }
        viewmodel.setTagIfAbsent(TAG_SAVED_STATE_HANDLE_CONTROLLER, controller);
        return viewmodel;
        ...
}

再看SavedStateHandleController .create()

SavedStateHandle在实例化时,通过consumeRestoredStateForKey()传入上次保存的数据,此时SavedStateHandle数据已完成恢复。
SavedStateHandleController创建后,通过attachToLifecycle()方法,在方法内部将SavedStateHandle维护的SavedStateProvider注册到SavedStateRegistry

前面说到SavedStateViewModelFactory是框架骨架之一,实际就是通过这个过程,最终允许VM能够把数据的存取加入到SaveInstanceState流程。

SavedStateHandleController.java
-------------------------------

static SavedStateHandleController create(SavedStateRegistry registry, 
                      Lifecycle lifecycle, String key, Bundle defaultArgs) {

    // 通过consumeRestoredStateForKey获取前次状态
    Bundle restoredState = registry.consumeRestoredStateForKey(key);
    // 创建一个Handle
    SavedStateHandle handle = 
                SavedStateHandle.createHandle(restoredState, defaultArgs);

    // 生成SavedStateHandleController实例
    SavedStateHandleController controller = 
                new SavedStateHandleController(key, handle);

    // 这里进行了绑定
    controller.attachToLifecycle(registry, lifecycle);
    tryToAddRecreator(registry, lifecycle);
    return controller;
}

void attachToLifecycle(SavedStateRegistry registry, Lifecycle lifecycle) {
    registry.registerSavedStateProvider(mKey, mHandle.savedStateProvider());
}

至此,SavedStateProviderSavedStateRegistry实现关联。

    • *

以上就是整个保存流程的概况,而还原流程差距不大,只是在onCreate()中调用SavedStateRegistryController.performRestore(),最终通知SavedStateRegistryBundle中恢复设置的数据。

    • *

忽略SavedStateHandleControllerVM的确保机制 (包含Recreator),最后总结:

  • 简化称呼以缩短阅读量:

    --
    VM组:
    `ViewModel` = `VM`
    `SavedStateViewModelFactory` = `Factory`
    --
    Registry组:
    `SavedStateRegistryController` = `RegistryController`
    `SavedStateRegistry` = `Registry`
    --
    Handle组:
    `SavedStateHandleController` = `HandleController`
    `SavedStateHandle` = `Handle`
    --
    Provider组:
    `SavedStateProvider` = `Provider`
    --
    
  • 初始化阶段:

    `ComponentActivity`创建了`RegistryController`实例
    `RegistryController`创建了内部的`Registry`实例
    `ComponentActivity`创建了`Factory`,并传入`RegistryController`维护的`Registry`
    
  • 恢复阶段

    `ComponentActivity`在`onCreate`调用`RegistryController`的`performRestore`
    `RegistryController`的`performRestore`中,调用`Registry`的`performRestore`
    `Registry`的`performRestore`中,把数据从`savedInstanceState (Bundle)`取出,并储存到`mRestoredState`中
    ***在此处`Registry`已把数据恢复***
    
  • VM生成阶段:

    `VM`需要通过`Factory`创建,创建过程:
    -- 创建`VM`对应的`HandleController`实例,创建过程:
    ------ 通过`Registry`的`consumeRestoredStateForKey`把数据取出生成`Handle`
    ------ `Handle`内部维护一个`Provider`实例,共享数据容器`mRegular`
    ------ `HandleController`被注入`Handle`
    ------ `Provider`绑定到`Registry`
    ------ ***在此处实现了 (`RegistryController`-`Registry`-`Provider`-`Handle`) 绑定***
    --`VM`被`Factory`注入`Handle`
    --***在此处实现了 (`RegistryController`-`Registry`-`Provider`-`Handle-VM`) 绑定***
    --***`VM`数据最终通过`Registry`恢复***
    
  • 写数据阶段

    `VM`读写的数据最终存放到`Handle`的`mRegular`中
    ***`VM`数据最终通过`Registry`保存***
    
  • 保存阶段

    `ComponentActivity`在`onSaveInstanceState`调用`RegistryController`的`performSave`
    `RegistryController`的`performSave`中,调用`Registry`的`performSave`
    `Registry`的`performSave`中,将所有注册的`Provider`数据打包成一个`Bundle`保存到`onSaveInstanceState`的`Bundle`中
    ***在此处`Registry`已把数据保存***
    

作者:七零八落问号
链接:https://www.jianshu.com/p/4a65ee05e6a1

相关文章
|
3月前
|
安全
一道面试题:介绍一下 LiveData 的 postValue ?
一道面试题:介绍一下 LiveData 的 postValue ?
34 0
|
数据可视化 Java
Java中的事件监听知识点&动作监听简单实现(含源码阅读)
监听分为三类:键盘监听、鼠标监听 和 动作监听,看到这些名词可能有点懵,监听是个啥,那么首先我们来理解一下绑定监听:当事件源(按钮)上发生了某个事件(单击),就执行某段代码(输出“您已点击按钮”)
270 0
Java中的事件监听知识点&动作监听简单实现(含源码阅读)
|
12月前
|
数据挖掘 Perl
Mummer 用法简析
Mummer 用法简析
83 0
|
前端开发
前端学习案例13-promise源码实现5
前端学习案例13-promise源码实现5
55 0
前端学习案例13-promise源码实现5
|
前端开发
前端学习案例12-promise源码实现4
前端学习案例12-promise源码实现4
52 0
前端学习案例12-promise源码实现4
|
前端开发
前端学习案例12-promise源码实现4
前端学习案例12-promise源码实现4
41 0
前端学习案例12-promise源码实现4
|
前端开发
前端学习案例13-promise源码实现5
前端学习案例13-promise源码实现5
46 0
前端学习案例13-promise源码实现5
|
前端开发
前端学习案例12-promise源码实现3
前端学习案例12-promise源码实现3
41 0
前端学习案例12-promise源码实现3
|
前端开发
前端学习案例10-promise源码实现1
前端学习案例10-promise源码实现
42 0
前端学习案例10-promise源码实现1
|
前端开发
前端学习案例11-promise源码实现2
前端学习案例11-promise源码实现2
51 0
前端学习案例11-promise源码实现2