Android静态对象生命周期


101

我正在创建事件搜索应用程序,我们从一个屏幕设置搜索条件,然后在另一个屏幕中填充,然后用户可以从第三个屏幕编辑搜索条件,然后转到第四个屏幕。

为了实现上述任务,我正在使用静态对象,该对象记住应用程序周围的值,而我不需要做任何其他事情。

但我担心,如果内存不足,Android会删除静态对象?

由于android支持多任务处理,如果用户切换到另一个应用程序,并且当用户回来时应用程序开始疯狂执行操作,则静态对象在执行多任务处理时是否会被移除?任何想法 ??并建议通过单例方法持有静态对象是更好的方法

Answers:


238

让我们从一些背景开始:启动应用程序时会发生什么?
操作系统启动一个进程并为其分配唯一的进程ID并分配一个进程表。一个进程启动DVM(Dalvik VM)的实例;每个应用程序都在DVM中运行。
DVM管理类加载卸载,实例生命周期,GC等。

静态变量的生存期:静态变量在JVM加载类时存在,而在卸载类时死亡。

因此,如果您创建一个android应用程序并初始化一个静态变量,它将保留在JVM中,直到发生以下情况之一:
1.卸载该类
2. JVM关闭
3.进程 终止

请注意,当您切换到另一个应用程序的不同活动时,静态变量的值将保持不变,并且以上三个都不发生。如果以上三种情况中的任何一种发生,则静电将失去其价值。

您可以使用以下几行代码进行测试:

  1. 在活动的onCreate中打印未初始化的静态->应该打印null
  2. 初始化静态。打印它->值将不为null
  3. 点击后退按钮并进入主屏幕。注意:主屏幕是另一项活动。
  4. 再次启动您的活动->静态变量将为非null
  5. 从DDMS(设备窗口中的停止按钮)中止您的应用程序进程。
  6. 重新启动活动->静态将为空值。

希望能有所帮助。


1
我想知道为什么在启动新活动时,如果应用程序对象中的字段值不是静态的,那么我会丢失该字段值,例如,我在应用程序对象中声明了当前变量页面,而当我打开新活动时,其值始终返回零
Mohammed Subhi Sheikh Quroush

当我调用super.onRestoreInstanceState(savedInstanceState); 即使变量是静态的,我也会丢失变量,这是什么问题?
Mohammed Subhi Sheikh Quroush

1
这是一个很好的解释(因此不为-1),但没有什么意义:OP明确询问“内存不足的情况”(我在这里的相同原因),据我所知,O可能会杀死VM,并且稍后使用相同的参数重新启动它,并且这种情况(如果是实物的话)不在此处...
Rick77 '16

1
@suitianshi我认为我们可以在Application.onCreate中初始化静态实例,因为即使我们的应用程序进入后台并且进程被杀死,只要回到我们的应用程序,Application类都将被实例化并调用其对应的生命周期方法再次!尽管我需要对此进行确认,但我想知道是否有可能出现Application.onCreate中初始化的静态实例丢失其值的情况?
Sarthak Mittal

1
我在这里所缺少的是对“ 1.类已卸载”的解释-什么时候会发生?如果JVM的内存不足,JVM会卸载它吗?
stoefln

16

好吧,单例模式也基于使用静态变量,因此实际上您将处于同一位置。尽管静态方法在大多数情况下都可以使用,但是在某些情况下,当内存已满并且其他活动占据了前台,然后您的应用程序移至下一个屏幕时,可能会发生,您的活动过程可能会被杀死,并且您会丢失静态值。但是,Android提供了一些在状态之间保留值或传输状态的方法,例如:

  • 使用Intent,您可以在活动之间传递搜索条件(类似于Web http请求)
  • 使用应用程序首选项,您可以保存值并在需要它们的活动中检索它们
  • 使用sqlite数据库,您可以将它们持久保存在表中,以后再检索
  • 如果您只需要保存活动状态,以便在重新启动时将这些字段填充为其先前选择的值,则可以实现onSaveInstanceState()活动方法-请注意,建议不要在活动的状态持久化之间使用此方法。

通过查看google代码或其他开放源代码Android应用程序中的盾构源代码树,可以获取一些使用首选项,意图和sqlite数据库的代码示例。


6

经过研究后,发现使用Application存储单例并不是一个好主意,除非您准备重新创建它:

不要将数据存储在应用程序对象中

因此,尽管已接受的答案在技​​术上是正确的,但并不能提供所有信息。

正如上面的链接所暗示的,如果您确实想坚持使用该模型,则需要准备检查空值并在可能的情况下重新创建数据。


3

@ r1k0就在这里。在类的静态字段中存储数据将不会在整个应用程序进程终止和重新启动时自行保留。Android通常会在需要内存时杀死进程(正在运行的应用程序)。

根据Android文档:活动状态和从内存中弹出

系统永远不会直接杀死活动。相反,它杀死了活动在其中运行的进程,不仅破坏了活动,而且还破坏了该进程中运行的所有其他事物。

您可以使用以下方法保存和还原基元以及可序列化和可打包对象的状态。在正常活动生命周期中会自动调用它们。

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

因此,如果您的类只包含静态变量,则可以将每个字段的状态保存在onSaveInstanceState()中,然后将其还原到onRestoreInstanceState()中。当Android终止您的应用程序正在运行的进程时,变量状态将被保存,而Android还原您的应用程序时,值将以与以前相同的状态恢复到内存中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.