概览
这本没什么可讲的,但是可能很多人并没有考虑过这个问题,而且我准备结合 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。在聊天列表页面,每次更新了列表中的联系人窗口数据都会使用数据库进行存储。那么就有一下三种场景了:
- Activity 初次创建
- Activity 配置发生更改导致 Activity 被重建
- Activity 所在进程被系统回收,再次进入被重建
针对 1:刚进入 Activity 的时候我们需要请求后台查看有没有增量的联系人,如果有拉取数据存储在本地数据库。
针对 2:的情况,Activity 被重建的时候,因为 ViewModel 没有被销毁,我们可以直接从 ViewModel 中恢复数据,不需要请求网络(当然了你为了保持数据的实时性去请求也无可厚非)
针对 3:的情况,我们可以在 onSaveInstanceState 中保存联系人的 id,Activity 被重建的时候拿到这个 id 去数据库中查找数据,这种情况也不需要请求网络。(当然了你为了保持数据的实时性去请求也无可厚非)