【背上Jetpack】绝不丢失的状态 androidx SaveState ViewModel-SaveState 分析

本文详细介绍了AndroidX中如何使用SavedState库处理Activity和Fragment的状态保存与恢复,包括SavedStateProvider、SavedStateRegistry等组件的工作原理,并探讨了状态保存的正确姿势。
摘要由CSDN通过智能技术生成

系列文章

【背上Jetpack】Jetpack 主要组件的依赖及传递关系

【背上Jetpack】AdroidX下使用Activity和Fragment的变化

【背上Jetpack之Fragment】你真的会用Fragment吗?Fragment常见问题以及androidx下Fragment的使用新姿势

【背上Jetpack之Fragment】从源码角度看 Fragment 生命周期 AndroidX Fragment1.2.2源码分析

【背上Jetpack之OnBackPressedDispatcher】Fragment 返回栈预备篇

【背上Jetpack之Fragment】从源码的角度看Fragment 返回栈 附多返回栈demo

前言

大家都知道 activity 有着一套 onSaveInstanceState-onRestoreInstanceState 状态保存机制,旨在「系统资源回收」或「配置发生变化」保存状态,为用户提供更好的体验

在 androidx 下,提供了 SavedState 库帮助 activity 和 fragment 处理状态保存和恢复

本文默认您对状态保存机制有一定了解,这部分内容请移步 Saving UI States

此外,关于 android 下的进程管理,推荐 Ian Lake 的 Who lives and who dies? Process priorities on Android

本文介绍了 androidx 下 SavedState 如何帮助 activity 和 fragment 处理状态的保存和恢复,同时介绍 viewmodel-savedstate 库,以及在开发过程中正确使用状态保存的姿势

软件工程中没有什么是中间层解决不了的

在分析 SavedState 库之前我们需要简单聊一聊 ComponentActivity

androidx activity 1.0.0 时,ComponentActivity 成为了 FragmentActivityAppCompatActivity 的基类。

androidx activity 1.0.0

俗话说「百因必有果」,带着强烈的好奇心,我查了一下 ComponentActivity 引入的原因。

可以看到 ComponentActivity 继承了 androidx.core.app.ComponentActivity(在 fragment 库中),并且最初仅实现了LifecycleOwner 接口

我们创建的 activity 的继承关系现在变成了这样:

那么回到最初的问题,为什么要引入 ComponentActivity ?其实看看现在 ComponentActivity 的类结构答案就很清楚了

ComponentActivity 实现了五个接口,代表着其除了 activity 还充当着五种角色。本着职能单一原则,官方通过建立一个中间层将部分功能分别交于专门的类来负责,OnBackPressedDispatcherOwner 就是我们讲 fragment 返回栈(【背上Jetpack之OnBackPressedDispatcher】Fragment 返回栈预备篇)时提到的结构,而其中的 SavedStateRegistryOwner 则是我们今天要讲的主角 SavedState 中的成员

SavedState

引入 SavedState

implementation "androidx.savedstate:savedstate:1.0.0"

其实您不需要显示地声明,因为 activity 库内部已经引入了。jetpack 组件依赖关系可参考 【背上Jetpack】Jetpack 主要组件的依赖及传递关系

这是一个很小的库

图片来自 Android ViewModels: State persistence — SavedState

SavedStateProvider

保存状态的组件,此状态将在以后恢复并使用

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

SavedStateRegistry

管理 SavedStateProvider 列表的组件,此注册表绑定了其所有者的生命周期(即 activity 或 fragment)。每次创建生命周期所有者都会创建一个新的实例

创建注册表的所有者后(例如,在调用 activity 的 onCreate(savedInstanceState) 方法之后),将调用其 performRestore(state) 方法,以恢复系统杀死其所有者之前保存的任何状态。

void performRestore(@NonNull Lifecycle lifecycle, @Nullable Bundle savedState) {
   
    // ...
    if (savedState != null) {
   
        mRestoredState = savedState.getBundle(SAVED_COMPONENTS_KEY);
    }
    // ...
}

每个注册表的 SavedStateProvider 都由用于注册它的唯一密钥标识

private SafeIterableMap<String, SavedStateProvider> mComponents = new SafeIterableMap<>();

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

Android Jetpack是Google提供的一套用于加速Android应用开发的工具包,其中包括了许多架构组件,其中之一就是ViewModelViewModel是一种设计模式,用于保存和管理与UI相关的数据。在传统的Android开发中,当屏幕旋转或者因为其他原因导致Activity或Fragment重建时,之前保存的临时数据就会丢失。而ViewModel的出现解决了这个问题。 ViewModel的主要作用是将数据与UI组件分离。它的工作方式是创建一个ViewModel类,并在其中保存需要与UI组件交互的数据。这样,当屏幕旋转或重建时,ViewModel实例不会销毁,数据也会得到保留。然后,在Activity或Fragment中,通过获取ViewModel实例,可以轻松地访问这些数据。 使用ViewModel的好处有很多。首先,它可以避免内存泄漏,因为ViewModel的生命周期与Activity或Fragment无关。其次,它可以节省资源,因为当Activity或Fragment销毁时,ViewModel实例可以被系统缓存起来,下次再创建时可以直接返回该实例。另外,由于ViewModel保存了与UI相关的数据,可以减少因为屏幕旋转导致的数据重复加载的问题。 在使用ViewModel时,你可以选择使用Android Jetpack中的其他架构组件来进一步提高开发效率,比如通过LiveData实现数据的观察和通知,或者通过DataBinding来实现UI与数据的自动绑定。 总之,ViewModel是Android Jetpack中非常重要的一个架构组件,它的出现实现了数据与UI的解耦,提高了开发效率,并且解决了数据丢失的问题。希望通过这篇文档的详解,你对ViewModel有了更深入的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值