2009-12-22 95 views
88

我正在创建事件搜索应用程序,我们从一个屏幕中设置搜索条件并将其填充到另一个屏幕中,然后用户可以从第3个屏幕编辑搜索条件并转到第4个屏幕。Android静态对象生命周期

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

但是我怕如果关于android中的静态对象生命周期如果内存不足发现android删除静态对象???

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

回答

215

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

静态变量的生存期:静态变量在类被JVM加载并在类卸载时死亡时出现。

因此,如果您创建一个Android应用程序,并初始化静态变量,它会留在JVM中,直到发生下列情况之一:
1类被卸载
2. JVM关闭
3。该进程死亡

请注意,当您切换到另一个应用程序的其他活动时,静态变量的值将会持续存在,并且上述三个操作都不会发生。如果上述三种情况发生,静态将失去其价值。

您可以用几行代码测试:

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

希望有所帮助。

+11

这是一个很好的解释,任何Android开发者都应该阅读。 – 2012-09-12 00:49:31

+1

我想知道为什么我失去应用程序对象中的字段值,如果它不是静态的,例如我开始新的活动时,例如我在应用程序对象中声明了可变的当前页面,并且当我打开新的活动时它的值总是返回到零 – 2013-02-14 11:12:42

+0

super.onRestoreInstanceState(savedInstanceState);即使它们是静态的,我也失去了我的变量,这是什么问题? – 2013-02-14 11:18:09

14

那么,Singleton模式也是基于使用静态变量,所以实际上你会处于相同的位置。虽然静态方法可能在大多数情况下都有效,但在某些情况下,当内存已满并且另一个活动在应用程序移至其下一个屏幕之前占用前台时,您的活动进程可能会被终止,并且会丢失静态值。 但是Android提供了国家之间持续存在的值或发送它们如的几个选项:使用意向

  • ,你可以沿着 从活动通过你的搜索条件 活动(类似于网页的HTTP 请求)
  • 使用应用程序的喜好,你 可以保存值,并在使用SQLite数据库需要它们
  • 活动检索 他们,你可以坚持 他们在一个表和检索 他们后来
  • ,如果你只是需要保存活动 状态,这样在重新启动时,场 得到填补,具有以前 选择的值,可以实现 的的onSaveInstanceState()活动 方法 - 请注意,这不是 推荐在活动 之间持续的状态。

您可以通过查看谷歌代码aegis-shield source code tree或其他开源的Android应用程序获取偏好,意图和SQLite数据库的使用的一些代码示例。

3

经过一番研究,事实证明,使用应用程序存储单身并没有很大的想法,除非你准备创建它:

Don't store data in the application object

因此而the accepted answer在技术上是正确的,它不提供所有信息。

正如上面的链接所暗示的,如果您确实想坚持使用该模型,您需要准备好检查null并重新创建数据(如果可能)。

1

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

每Android的文档:Activity state and ejection from memory

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

您可以使用以下方法保存和恢复基元的状态以及Serializable和Parcelable对象。这些会在正常的活动生命周期中自动调用。

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

所以,如果你有一个只有静态变量的一类,可以节省每个字段的onSaveInstanceState中()状态,并在onRestoreInstanceState恢复它们()。当Android终止您的应用程序运行的进程时,变量的状态将被保存,并且当Android恢复您的应用程序时,这些值将以与以前相同的状态在内存中恢复。