【Android】static变量与App状态缓存

App启动,static变量装载过程

  1. 启动App
  2. OS开启新Process进程并分配进程ID(PID)及进程表
  3. 进程启动DVM实例(Dalvik VM,沙箱模式,每个App均运行在各自DVM内)
  4. DVM负责管理class类的装载、卸载、类实例的生命周期、GC回收等过程
  5. class类装载到DVM时,分配static变量空间并进行变量值初始化

static变量一旦初始化,将由JVM负责维护管理,除非遇到以下情形:

  • class类被卸载
  • JVM(DVM)被关闭
  • Process进程被终止

※ 随时对后台进程进行清理、回收任意资源并释放内存,此时static变量、实例变量将永久丢失数据,因此必须充分考虑在Application中缓存的数据的外部持久化及现场恢复问题,否则容易产生NullPointerException问题。尤其不应缓存、强依赖Context对象,必要时尽量考虑使用ApplicationContext取代。

Application中的缓存变量应该在onCreate方法中进行初始化,并且在 onLowMemory / onTrimMemory 中进行持久化存储。

Activity中的数据持久化不应该放在 onSaveInstanceState / onRestoreInstanceState 中进行,因为这两个方法不属于生命周期回调过程,不保证触发时机,应考虑在 onPause / onResume中执行持久化逻辑。


关于 onLowMemory 与 onTrimMemory

  • Android 4.0之后提供的API,用于系统通知内存不足,App进行必要的内存释放和现场保存
  • 在Application、Activity、Fragement、Service、ContentProvider中都实现了该接口
  • 也可通过 ComponentCallbacksComponentCallbacks2 注册监听器,实现外部监听
  • 内存不足时,依据当前App在后台App列表中的位置变化,多次触发 onTrimMemory 进行通知(此时当前App不会马上成为被清理对象)
  • 内存严重不足,并且当前App作为即将(下一个)被清理对象时回调 onLowMemory
  • 一键清理内存时不触发 onLowMemory,仅触发一次 onTrimMemory
参考:
  • Android static object lifecycle
  • How to declare global variables in Android?(关于如何派生、使用Application类存储全局变量的讨论)
  • Where Did My Static Data Go?
  • 应用内存优化之 OnLowMemory & OnTrimMemory
  • 不要在Android的Application对象中缓存数据!
  • 莫往Applicaotion存缓存/app被系统回收之后再打开发生了什么

你可能感兴趣的:(【Android】static变量与App状态缓存)