Android 状态恢复方案研究

需求

Android 系统在低内存环境下可能回收非前台显示的 Activity/Application。(eg. Activity 不在栈顶,Application 后台运行)用户返回 app 时,Android 系统会执行 Activity/Application 的恢复重建,开发者需要添加必要的状态保存 & 状态恢复代码,以保证 Activity/Application 恢复重建后用户可以回到其销毁前的状态,比如恢复用户正在编辑的内容。

参考:Android app 被系统 kill 的场景

状态保存 & 恢复方案

1. save/restoreInstanceState

Android Framework 实现的一套专用于状态保存&恢复的 api。

  • 优点
    • 保存&恢复机制由 Android 系统默认实现,便于使用,在 Activity/Fragment/View 中都有对应方法
    • Application 被杀不影响数据恢复
  • 缺点
    • 状态保存数据量有 1mb 大小的限制,数据超出 1mb 会抛出 TransactionTooLargeException

2. StatedFragment

使用 Fragment 缓存 Activity 中的状态量,原理是利用 Fragment 回收时只销毁 view,不销毁 Fragment 实例的机制。

3. Application memoryCache

将数据缓存至 Application 实例。

  • 优点
    • 数据缓存大小不受 1m 限制
  • 缺点
    • Application 被杀后数据丢失
    • 需要自己实现一套保存恢复机制

4. storageCache

将数据缓存至物理存储器中,Android 系统提供了三种存储方式,filesharedPreferencedatabase

  • 优点
    • 数据缓存大小不受 1m 限制
    • Application 被杀不影响数据恢复
  • 缺点
    • Application 被杀后数据丢失
    • 需要自己实现一套保存恢复机制
    • database 的管理(升降级等)需要额外的维护成本
    • SharedPreference 的频繁读写性能较差

个人选择的方案

我最终选择了 database + save/restoreInstanceState 来实现状态保存&恢复机制。

  • 对于大部分状态数据量小的界面,直接使用 save/restoreInstanceState 保存状态量,推荐一个直接生成 save/restore 辅助代码的库:bundler
  • 对于缓存数据量大的界面,添加一个 CacheModel 类,将所有需要缓存数据放置于 CacheModel 对象中,存储在 database,并将 CacheModel主键 通过 save/restoreInstanceState 保存。(这个方法是受到 StatedFragment 的启发)