106

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

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

但是如果发现内存不足,我担心android中的静态对象生命周期会删除静态对象???

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

4

4 回答 4

244

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

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

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

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

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

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

希望有帮助。

于 2009-12-22T06:46:47.390 回答
17

好吧,单例模式也是基于使用静态变量,所以实际上你会处于相同的位置。虽然静态方法可能在大多数情况下都有效,但在某些情况下,当内存已满并且另一个活动在您的应用程序移动到下一个屏幕之前占据前台时,您的活动进程可能会被终止并且您会丢失静态值。然而,Android 提供了一些在状态之间保持值或传输它们的选项,例如:

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

通过查看google 代码或其他开源 Android 应用程序中的aegis-shield 源代码树,您可以获得一些使用偏好、意图和 sqlite 数据库的代码示例。

于 2009-12-22T10:24:06.930 回答
6

经过一番研究,事实证明,使用 Application 来存储单例并不是一个好主意,除非你准备好重新创建它:

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

因此,虽然接受的答案在技术上是正确的,但它并没有提供所有信息。

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

于 2016-12-07T14:22:33.357 回答
3

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

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

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

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

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

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

于 2017-04-12T00:47:14.767 回答