activity状态保存和恢复,高手退避

简介: activity状态保存和恢复,高手退避

概览


这本没什么可讲的,但是可能很多人并没有考虑过这个问题,而且我准备结合 ViewModel 讲一下状态的恢复和保存


状态保存


用户 activity 被系统销毁或者配置发生更改(例如旋转),此种情况当 activity 再次被重建用户的角度是希望看到他之前的状态的。因此我们可以使用 onSaveInstanceState 和 ViewModel 结合来实现状态的保存。


使用 ViewModel 进行状态保存

配置更改导致的状态保存

ViewModel 将数据保留在内存中,因此 ViewModel 的数据存储是非常快的。当配置更改 activity 被销毁 ViewModel 会保留在内存中。再次打开重建该 activity 的时候 ViewModel 可以与 activity 自动重新关联。


用户主动销毁 activity

如果是用户主动点返回键或者 finish 调用。则 ViewModel 会被清理出内存。


系统自动回收 activity

与前面两种情况不同,进程被系统回收的时候,activity 对应的 ViewModel 也会被回收。但是 activity 被重建的时候用户的角度肯定是希望 activity 状态和回收前一样的。这种情况就需要将 ViewModel 和 onSaveInstanceState 结合起来进行使用了。


持久化存储


onSaveInstanceState 只运行在主线程中并且存储的状态是被序列化到磁盘中的,所以我们只能在 onSaveInstanceState 中存储少量的基础类型或 String。

ViewModel 存在于 Activity 的生命周期内,因此只要应用进程没有被杀死,ViewModel 就可以保存状态,ViewModel 属于内存级别的状态保存。


总结一下:onSaveInstanceState 只能保存少量数据,ViewModel 只能保存数据到内存。所以对于更大的数据状态保存我们应该放在磁盘文件中或者使用数据库处理。

比如这样一个场景,我们的应用是一个 im 的即时通讯 app。在聊天列表页面,每次更新了列表中的联系人窗口数据都会使用数据库进行存储。那么就有一下三种场景了:

  1. Activity 初次创建
  2. Activity 配置发生更改导致 Activity 被重建
  3. Activity 所在进程被系统回收,再次进入被重建


针对 1:刚进入 Activity 的时候我们需要请求后台查看有没有增量的联系人,如果有拉取数据存储在本地数据库。

针对 2:的情况,Activity 被重建的时候,因为 ViewModel 没有被销毁,我们可以直接从 ViewModel 中恢复数据,不需要请求网络(当然了你为了保持数据的实时性去请求也无可厚非)

针对 3:的情况,我们可以在 onSaveInstanceState 中保存联系人的 id,Activity 被重建的时候拿到这个 id 去数据库中查找数据,这种情况也不需要请求网络。(当然了你为了保持数据的实时性去请求也无可厚非)



相关文章
|
5月前
ContentProvider的执行时机
ContentProvider的执行时机
28 0
|
6月前
|
Android开发
Activity启动模式完全解读-更新中
Activity启动模式完全解读-更新中
72 0
Activity中,View#postDelay会导致内存泄漏,但是不会影响Activity的生命周期执行。
Activity中,View#postDelay会导致内存泄漏,但是不会影响Activity的生命周期执行。
Activity的四种状态
一个Activity实质上有四种状态:运行,暂停,停止,销毁
170 0
|
Android开发
Activity三种状态
Activity三种状态
486 0
|
存储 JSON API
项目中多次操作SharedPreferences导致ANR场景的解决
随着时代的进步,移动端广告的投放变得越来越多样化,为了接近市场,不少公司自己研发了SDK去收集用户的一些信息以及行为用于分析,根据分析结果使用自定义广告(自定义View)的方式继续向用户进行展示,以提高展示率和点击率。目前关于广告商方面的选择,国内的广告变现普遍较低,首选应该是接入谷歌广告。随着业务的发展,在一段时间后,公司开始转变成广告接收方,并靠自己的SDK来进行广告的投放,以及优化。
项目中多次操作SharedPreferences导致ANR场景的解决
FragmentTabHost中切换Fragment保存状态
import android.content.Context; import android.content.res.TypedArray; import android.
1014 0