Android 状态恢复方案研究
需求
Android 系统在低内存环境下可能回收非前台显示的 Activity/Application。(eg. Activity 不在栈顶,Application 后台运行)用户返回 app 时,Android 系统会执行 Activity/Application 的恢复重建,开发者需要添加必要的状态保存 & 状态恢复代码,以保证 Activity/Application 恢复重建后用户可以回到其销毁前的状态,比如恢复用户正在编辑的内容。
状态保存 & 恢复方案
1. save/restoreInstanceState
Android Framework 实现的一套专用于状态保存&恢复的 api。
- 优点
- 保存&恢复机制由 Android 系统默认实现,便于使用,在 Activity/Fragment/View 中都有对应方法
- Application 被杀不影响数据恢复
- 缺点
- 状态保存数据量有 1mb 大小的限制,数据超出 1mb 会抛出
TransactionTooLargeException
- 状态保存数据量有 1mb 大小的限制,数据超出 1mb 会抛出
2. StatedFragment
使用 Fragment 缓存 Activity 中的状态量,原理是利用 Fragment 回收时只销毁 view,不销毁 Fragment 实例的机制。
- 优点
- 数据缓存大小不受 1m 限制
- 缺点
- Application 被杀后数据丢失
- 需要自己实现一套保存恢复机制
3. Application memoryCache
将数据缓存至 Application 实例。
- 优点
- 数据缓存大小不受 1m 限制
- 缺点
- Application 被杀后数据丢失
- 需要自己实现一套保存恢复机制
4. storageCache
将数据缓存至物理存储器中,Android 系统提供了三种存储方式,file
,sharedPreference
,database
- 优点
- 数据缓存大小不受 1m 限制
- Application 被杀不影响数据恢复
- 缺点
- Application 被杀后数据丢失
- 需要自己实现一套保存恢复机制
- database 的管理(升降级等)需要额外的维护成本
- SharedPreference 的频繁读写性能较差
个人选择的方案
我最终选择了 database
+ save/restoreInstanceState
来实现状态保存&恢复机制。
- 对于大部分状态数据量小的界面,直接使用
save/restoreInstanceState
保存状态量,推荐一个直接生成 save/restore 辅助代码的库:bundler - 对于缓存数据量大的界面,添加一个
CacheModel
类,将所有需要缓存数据放置于CacheModel
对象中,存储在database
,并将CacheModel
的主键
通过save/restoreInstanceState
保存。(这个方法是受到StatedFragment
的启发)