读完这篇文章,你会知道什么?

  1. 为什么 ViewModel#onClear 履行在 Activity#onDestory 之前,但生命周期比 Activity
  2. LifecycleObserver 是怎样兼容 LifecycleEventObserverDefaultLifecycleObserver
  3. SavedStateRegistry 作业机制和触及每个类的责任
  4. ViewModel 创立进程中触及每个类的责任
  5. SavedStateHandle 效果及两种创立进程的差异
  6. rememberSaveable 状况存储进程中触及每个类的责任
  7. Compose NavHost 是怎样自定义 LifecycleOwnerViewModelStoreOwnerSavedStateRegistryOwnerSaveableStateRegistry

Lifecycle 组件

相关成员

  1. LifecycleOwner: Lifecycle 的所有者,用于供给 Lifecycle
  2. LifecycleRegistry: Lifecycle 的子类,能够直接运用然后快速自定义生命周期办理和监听分发
  3. LifecycleObserver: 生命周期观察者, 用于监听生命周期的改变,默许子类有 LifecycleEventObserverDefaultLifecycleObserver
  • Tips: ComponentActivity 运用 ReportFragment 调用 LifecycleRegistry 分发本身生命周期

疑问:

  1. ViewModel#onClear 的履行是在 Activity#preDestory 的时分调用,为什么说 ViewModel 的生命周期比 Activity
  1. ViewModel#onClear 履行的时分,会判别是否由于装备改变导致的 Activity 销毁,假如不是则履行 ViewModel#onClear;假如是的话,则不履行 ViewModel 的整理作业
  2. 在因装备修正导致 Activity 重启的时分,会存储当时 ComponentActivity#ViewModelStoreActivityThread#ActivityClientRecord#lastNonConfigurationInstances
  • 调用链: ActivityThread#performDestroyActivity -> Activity#retainNonConfigurationInstances -> ComponentActivity#onRetainNonConfigurationInstance
  • ComponentActivity#onRetainNonConfigurationInstance 办法可知,ComponentActivity子类 可重写 onRetainCustomNonConfigurationInstance 办法来持有 不因装备修正的状况;不过已经被抛弃,运用 ViewModel 来存储 不因装备修正的状况
  1. 在因装备改变重启 原Activity 的时分,ActivityThread#performLaunchActivity 会调用 activity#attch 一起会带着前次保存的 Activity#NonConfigurationInstances 状况
  2. ComponentActivity#getViewModelStore 中,会先 Activity#NonConfigurationInstances#activity 字段获取到 ComponentActivity#NonConfigurationInstances#viewModelStore,然后康复重启之前的 ViewModel 数据

相关类

// Activity
static final class NonConfigurationInstances {
    Object activity;   // 一般为ComponentActivity#NonConfigurationInstances
    HashMap<String, Object> children;
    FragmentManagerNonConfig fragments;
    ArrayMap<String, LoaderManager> loaders;
    VoiceInteractor voiceInteractor;
}
// ComponentActivity下
static final class NonConfigurationInstances {
    // 能够重写 ComponentActivity#onRetainCustomNonConfigurationInstance 注入
    Object custom; 
    // 存储了ComponentActivity#ViewModelStore
    ViewModelStore viewModelStore;  
}
  1. 为什么 LifecycleObserver 没有任何办法定义

LifecycleObserver 没有任何完成,是由于原先运用办法是 自定义办法 加上 对应生命周期注解 运用的,在 androidx.lifecycle-*:2.4.0 被抛弃了,所以是没有任何办法定义

class CustomLifecycleObserver : LifecycleObserver {
    @@OnLifecycleEvent(Lifecycle.Event.ON_STOP)  
    fun onStop() {
        // ...
    }
}
  1. 体系是怎样完成注入 LifecycleEventObserver 或者 DefaultLifecycleObserver 都能够正常收取对应到回调
  • LifecycleEventObserver: 需求完成 onStateChanged
  • DefaultLifecycleObserver:需求完成 onCreateonStartonResumeonPauseonStoponDestory
  • 经过 LifecycleRegistry#addObserver 可知,传入的 observer 会经过 Lifecycling.lifecycleEventObserver 最终仍是转换为 LifecycleEventObserver; 能够看到本质仍是经过LifecycleEventObserver 的办法转换调用 DefaultLifecycleObserveronCreate 等办法
  • 一起由 FullLifecycleObserverAdapter 可知, 假如 Observer 一起完成 LifecycleEventObserverDefaultLifecycleObserver 都会调用对应的回调
  1. 生命周期是 跳动式 的仍是 递进式
  • LifecycleRegistrybackwardPassforwardPass 可知,状况是一级一级的递进,而不是突然跳动

SavedStateRegistryOwner

  • androidX 依据 ActivityonSaveInstanceStateonCreate 封装的一套API,能够在需求存储数据的时分履行 SavedStateRegistry#performSave,在需求康复数据的时分履行 SavedStateRegistry#performRestore
  • 其中存储的数据需求支持序列化 Parcelable

相关成员

  1. SavedStateRegistryController
  2. SavedStateRegistry
  3. SavedStateRegistryOwner

SavedStateRegistryController 责任

  1. performAttch: 注入 Recreator 和履行 SavedStateRegistry#performAttch
  2. performRestore 调用 SavedStateRegistry#performRestore
  3. performSave 调用 SavedStateRegistry#performSave

Recreator 责任

  1. 用于保存 SavedStateRegistry#AutoRecreated 的调集
  2. 在康复的时分,主动创立和调用 SavedStateRegistry#AutoRecreated 的调集

SavedStateRegistry 责任

  1. SavedStateProvider 用于供给怎样保存状况的接口
  2. SavedStateRegistry 被重启的时分,会主动创立已加入 AutoRecreated 调集相关的类; 经过 SavedStateRegistry#runOnNextRecreation 增加到主动创立列表中
  3. 存储和康复相关办法: performSave(保存存储状况) 和 performRestore(获得存储状况)
  4. 经过 registerSavedStateProviderunregisterSavedStateProvider 键值对办法办理 SavedStateProvider
  5. 经过 consumeRestoredStateForKey 获取 存储的状况信息

ComponentActivitySavedStateRegistry 交互代码

public class ComponentActivity {
    // ..
    public ComponentActivity() {
        // ...
        mSavedStateRegistryController.performAttach(); // 关联
        // ..
    }
    // ..
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        // ...
        // 康复数据到 SavedStateRegistry
        mSavedStateRegistryController.performRestore(savedInstanceState);
        // ..
    }
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        // ..
        // 存储当时状况 - 每次 onPause 事件发生的时分履行
        mSavedStateRegistryController.performSave(outState);
    }
}

疑问:

  1. 为什么不运用 onSaveInstanceState 对应的 onRestoreInstanceState 来履行康复,而运用 onCreate?

猜想: onRestoreInstanceStateframework 在第一次分发 onStart 的时分履行;
onSaveInstanceStateframework 每次分发 onPause 的时分履行保存状况;
onCreate 履行康复, 猜想是为了更早的康复,源码内置了挺多依据生命周期 onCreate 消费康复数据的

  • Tips: 其中状况都是从 ActivityClientRecord#state 上获取

SavedStateHandle – ViewModel 的状况存储和康复东西

  • SavedStateHandle 最终也是挂载 SavedStateRegistry 上完成状况存储和康复的,所以也是需求存储的内容是能够被序列化的

ViewModel 创立的相关类

  1. ViewModelStore: 用于寄存 ViewModel 实例
  2. ViewModelProvider.Factory: 负责怎样创立 ViewModel 实例
  3. ViewModelProvider: 负责控制 ViewModelStoreViewModelProvider.Factory 的履行流程
  4. CreationExtra: 能够带着 ViewModel 创立参数,需求与 ViewModelProvider.Factory 合作运用
  5. HasDefaultViewModelProviderFactory: 在运用 ViewModelStoreOwner 创立 ViewModelProvider 的时分,假如当时 owner 归于 HasDefaultViewModelProviderFactory 完成,则会从中提取默许的 ViewModelProvider.FactoryCreationExtra;
  • 由于 androidx.activity.ComponentActivity 完成 HasDefaultViewModelProviderFactory,所以运用 ViewModelProvider(this) 是能够创立出带 SavedStateHandleViewModel
  • 其实能从 ComponentActivity#getDefaultViewModelCreationExtras 的完成可知,依据键值对的办法注入了一些常用参数
// androidx.activity.ComponentActivity 的完成
public CreationExtras getDefaultViewModelCreationExtras() {
    MutableCreationExtras extras = new MutableCreationExtras();
    if (getApplication() != null) {
        extras.set(ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY, getApplication());
    }
    extras.set(SavedStateHandleSupport.SAVED_STATE_REGISTRY_OWNER_KEY, this);
    extras.set(SavedStateHandleSupport.VIEW_MODEL_STORE_OWNER_KEY, this);
    if (getIntent() != null && getIntent().getExtras() != null) {
        extras.set(SavedStateHandleSupport.DEFAULT_ARGS_KEY, getIntent().getExtras());
    }
    return extras;
}

SavedStateHandle

  • AbstractSavedStateViewModelFactory 源码可知,SavedStateHandle 有2种创立办法
  1. SavedStateHandleSupport#createSavedStateHandle 创立办法;会创立一个 SavedStateHandlesProvider 专门办理 SavedStateHandle 存储和康复,一起在创立 SavedStateHandlesProvider 的时分会主动挂载 SavedStateRegistry 身上和 装载康复的数据
// 在结构函数的时分的时分调用, 创立 SavedStateHandlesProvider
fun <T> T.enableSavedStateHandles()
    where T : SavedStateRegistryOwner, T : ViewModelStoreOwner {
    val currentState = lifecycle.currentState
    require(
        currentState == Lifecycle.State.INITIALIZED || currentState == Lifecycle.State.CREATED
    )
    if (savedStateRegistry.getSavedStateProvider(SAVED_STATE_KEY) == null) {
        val provider = SavedStateHandlesProvider(savedStateRegistry, this)
        // 将 SavedStateHandlesProvider 注册到 savedStateRegistry
        savedStateRegistry.registerSavedStateProvider(SAVED_STATE_KEY, provider)
        lifecycle.addObserver(SavedStateHandleAttacher(provider))
    }
}
internal class SavedStateHandleAttacher(
    private val provider: SavedStateHandlesProvider
) : LifecycleEventObserver {
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        check(event == Lifecycle.Event.ON_CREATE) {
            "Next event must be ON_CREATE, it was $event"
        }
        source.lifecycle.removeObserver(this)
        // 康复数据
        provider.performRestore()
    }
}
  1. LegacySavedStateHandleController 办法创立,由对应的 ViewModel 持有 Controller, 此 Controller 主要是用于挂载 SavedStateRegistry装载康复数据
  • Tips:由于 ViewModel 持有 LegacySavedStateHandleController, 所以在 界面装备修正,会进行界面重启;但此时 ViewModel 已经生成,所以内部完成了 SavedStateRegistry.AutoRecreated 用于在这种状况将 SavedStateHandle 从头挂载到 SavedStateRegistry

疑问

  1. 默许 ViewModel#key 怎样决议的

默许由 ViewModelProvider#get 办法决议, 值为 androidx.lifecycle.ViewModelProvider.DefaultKey:${modelClass.canonicalName}, 也能够调用双参数的办法进行自定义 key 传入

  1. SavedStateHandle#savedStateProvidersavedStateRegistry 中的注册的 key 是什么

是运用 ViewModel#key 注册的,在默许状况下,重启康复 key 也不会发生改变,然后能够正确康复状况

  1. ViewModelSavedStateHandle 的关系

ViewModelSavedStateHandle 是1对1的关系;默许是运用 ViewModel#keysavedStateRegistry 注册 SavedStateProvider 用于保存数据和康复数据的

  1. 2种创立 SavedStateHandle 有什么差异
  • 关于运用方来说, 2种创立得到 SavedStateHandle 运用办法是完全一致的;
  • 我翻了一下 ViewModel-SavedState 库的历史记录,发现 LegacySavedStateHandleController 是最开始创立 SavedStateHandle 的一套;
  • 而经过 CreationExtras.createSavedStateHandle 创立 SavedStateHandle 是中途新加入的一种创立办法;
  • 二种办法共存应该是兼容新老版本的交替运用

SaveableStateRegistry(Compose的状况存储)

DisposableSaveableStateRegistry 责任

  1. 挂载到 Android Lifecycle SavedStateRegistry 上,调用 SaveableStateRegistry#performSave 存储和 带康复数据创立 SaveableStateRegistry
  2. 扩展 SaveableStateRegistry 功用,增加 onDispose 办法,取消 Android Lifecycle SavedStateRegistry 注册

SaveableStateRegistry 责任

  1. canBeSaved: (Any) -> Boolean : 判别检查存储目标是否合法
  2. consumeRestored: 耗费康复数据
  3. registerProvider + Entry: 注册和反注册存储回调,一次注册 [key] -> [() -> Any?]
  4. performSave: 存储当时已注册的 Provider已康复未耗费的数据

rememberSaveable 责任

  1. 履行 SaveableStateRegistry#consumeRestored 耗费缓存数据
  2. 进入的时分调用 SaveableStateRegistry 注册,在离开界面的时分进行 SaveableStateRegistry 反注册

Saver 责任

  1. 用于从 SaveableStateRegistry 康复的数据转换成 业务数据
  2. 用于 业务数据 转成可被 SaveableStateRegistry 康复存储的 数据
  • Tips: 存储的时分带着 SaverScope 是能够用来调用 SaveableStateRegistry#canBeSaved,判别目标是否能够被保存
  • Saver 相关衍生目标有三个:
  1. listSaver: 把 目标 拆分红 list, 然后把 list 转换成 目标
  2. autoSaver: saver 的默许完成,不会做任何转换
  3. mapSaver: 把 目标 拆分红 map, 然后把 map 转换成 目标,底层运用 listSaver 完成

疑问

  1. 康复是指定 key 对应一个 List<Any?>, 但注册是一个 key 对应一个 () -> Any?

答: 在 Composable 或许会一起取相同的 key,依照先后顺序,能够确认所需求的方位,由于只有 rememberSaveable 能消费,除非开发者自定义导致异常,否则一般不会出现问题

Composable – NavHost 自定义 owner

自定义 NavBackStackEntry#LifecycleOwner

  • 当时生命周期 = Math.min(外部生命周期, 内部生命周期)
  • 外部生命周期 监听外部 Lifecyle 可得
  • 内部生命周期NavController 分发可得

自定义 NavBackStackEntry#ViewModelStoreOwner

  1. 运用外部 ViewModelStore 创立一个 NavControllerViewModelkeyandroidx.lifecycle.ViewModelProvider.DefaultKey:${modelClass.canonicalName},则 ViewModelStore 不变的状况先,每次获取的 NavControllerViewModel 为同一个
  2. 在创立 NavBackStackEntry 的时分,会传入 NavControllerViewModel 实例
  3. 获取 NavBackStackEntry#viewModelStore 的时分,会从 NavControllerViewModel 加上本身 NavBackStackEntry#id[UUID] 获取到对应 ViewModelStore, UUID不变则获取的 ViewModelStore 也不变
  • Tips: NavControllerViewModel 本身便是 ViewModel 也是 NavViewModelStoreProvider, 用于供给 ViewModelStore 和办理已供给的 ViewModelStore

自定义 NavBackStackEntry#SavedStateRegistryOwner

  1. NavBackStackEntry 履行初次更新生命周期的时分履行 savedStateRegistryController#performAttachsavedStateRegistryController#performRestore 用于挂载和康复savedStateRegistry
  2. 在每次 NavBackStackEntry 存储状况的时分,会调用本身 NavBackStackEntry#saveState 用于存储本身 SavedStateRegistry 状况

自定义 NavBackStackEntry#SaveableStateRegistry

  1. 运用 rememberSaveableStateHolder 创立 SaveableStateHolder,一起 SaveableStateHolder#parentSaveableStateRegistry 会赋值为LocalSaveableStateRegistry.current
  2. 利用 NavBackStackEntry#ViewModelStoreOwner创立一个 BackStackEntryIdViewModel, 用于供给 仅有idonCleared 办法移除当时状况、弱引证 SaveableStateHolder
  3. 运用 仅有id子Composable 生成一个 RegistryHolder, 用于控制内部 SaveableStateRegistry 的存储和数据康复
  4. 运用 RegistryHolder#registry子Composable 供给新的 LocalSaveableStateRegistry 的环境
  5. DisposableEffect#进入组合 移除状况(已康复了)增加RegistryHolder, DisposableEffect#onDispose 存储状况移除RegistryHodler

疑问

  1. ViewModel#onClearDisposableEffect 都有做清除操作,区别是什么

答: SaveableStateHolder的生命周期是附归于父的SaveableStateRegistry; ViewModel#onClear 是界面退出的时分调用,所以从弱引证获取 saveableStateHolderRef 移除本身状况,不用在保存和康复;而 DisposbaleEffect 是每次进入组合都会履行,所以在进入组合的时分提取状况,退出组合保存状况;

自定义 SavedStateHandle: 或许是用于 NavBackStackEntry 本身数据存储和康复

  1. NavResultSavedStateFactoryNavBackStackEntry#ViewModelStore 生成 SavedStateViewModel
  2. SavedStateViewModel 获取 handle

NavHost

  1. 获取当时 LifecycleOwner, 设置 LifecycleObserver, 用于分发当时生命周期到 NavController#backQueue
  2. 设置当时 ViewModelStore, 生成一个 NavControllerViewModel
  3. 运用当时 NavBackStackEntry子Composable 供给 LifecycleOwnerViewModelStoreOwnerSavedStateRegistryOwner 环境, 运用创立的 SaveableStateHandler 供给 SaveableStateRegistry
  • Tips: SaveableStateHandler 是存储在 SaveableStateRegistry,并供给 SaveableStateRegistry
  • Tips: NavControllerViewModel 运用父环境的 ViewModelStore 存储,依据 BackStackEntry#id 生成对应的 ViewModelStore
  • Tips: NavBackStackEntry 完成 SavedStateRegistry, 能够康复和存储数据

总结

ViewModel#SavedStateHandleCompose#SaveableStateRegistry 来看,可见状况存储和康复本质仍是依托 SavedStateRegistry, 而 SavedStateRegistry 又是依托 Activity 本身的 onSaveInstanceState 存储和康复机制的;