44

当我在主要活动中将变量声明并初始化为静态并且活动被破坏时。我还能访问变量的内容吗?

例如,始终访问我存储到此变量的 AsyncTask?我想要的是在方向改变后也能够访问它。

4

15 回答 15

25

静态变量与一个类相关联,只要类在内存中,它们就会存在,并在类被卸载时销毁(这种情况很少发生)。

在 Android 中,您已经看到,当我们关闭任何应用程序时,它并没有完全关闭,它仍保留在最近的应用程序堆栈中,您可以通过按住主页按钮(在大多数设备上)来查看。

当其他应用程序需要内存时,Android 本身会踢出那些最近的应用程序

于 2013-07-27T18:07:28.337 回答
8

如果进程被终止,那么所有静态变量都将重新初始化为其默认值。

这主要是因为,当您重新启动应用程序时,会创建一个新实例并重新初始化静态变量。

于 2013-07-27T17:21:28.963 回答
6

静态变量与类本身相关联。只要类在内存中,变量就会被保留。

类很少会被垃圾收集,因为它们存在于所谓的Permanent Generation内存空间中(您可以在此处找到有关分代 GC 工作原理的更多信息https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index .html)。

您可以查看https://developer.android.com/topic/performance/memory-overview以更好地了解 Android 中的内存管理方式,但除非您的应用程序正在做一些非常非常不寻常的事情,否则会分配永久代它需要保存所有类的所有内存,并且不会被垃圾收集。

方向更改不会清除静态变量,但是如果这是您的目标,则使用静态变量不是很合适。setRetainInstance您可以通过使用或类似方法在方向更改时保持实例状态(请参阅Android:如何防止在方向更改时清除类变量以获得答案)

于 2019-08-25T18:25:25.013 回答
4

我还能访问变量的内容吗?

假设“销毁”是指用户按 BACK 之类的东西,是的。

静态数据成员在进程的整个生命周期中都存在。

例如,始终访问我存储到此变量的 AsyncTask?我想要的是在方向改变后也能够访问它。

这不是一个合适的解决方案。使用保留的片段,或使用onRetainNonConfigurationInstance().

于 2013-07-27T17:22:14.213 回答
4

一旦封闭类加载到内存中,就会创建静态变量。您可以在加载时在静态块中初始化静态变量,或者在代码已经像您的情况一样运行时初始化静态变量。静态变量与类型相关,而不是类型的单个实例,因为一旦创建了静态变量,它就与包含它的进程一样存在(在 android 中,这意味着它与应用程序一起存在)。它可能导致的问题是:

  • 上下文泄漏(如活动):静态变量保持对上下文或对象(如视图)的引用,该对象保持对它的引用。
  • 巨大的内存负担:如果在生命范围比应用程序短的类型中使用静态变量,进程会保持所有静态变量处于活动状态。例如,在十个活动中,您将位图保留为静态变量。在这种情况下,所有位图都处于活动状态并占据内存中的位置。最后,内存和系统无法承受负担,抛出MemoryOutBoundException。
  • 崩溃:例如在场景中,您在活动中创建一个对象,然后将其作为静态变量存储在活动中。然后,您进入下一个活动。在第二个活动中,您确定前一个活动的静态变量不为空,并且大多数情况下它是正确的。但是,如果系统终止进程并重新创建它,则静态变量不会保留其对象。我想说的是,在事件驱动的环境中,管理静态变量并不是一件容易的事。

对于您的情况:ViewModel 架构组件在配置更改中保留对象。您可以使用它,但是您仍然需要小心上下文泄漏。另一种选择是使用没有 UI 的片段。您在片段中调用函数setRetainInstance(true),系统会在配置更改中保留此片段。此片段保留您的数据,您可以在配置更改发生后通过片段管理器获取此片段。实际上后一个选项是 ViewModel 的底层机制。对于像 AsyncTask 这样的多线程情况,在单独线程中运行的操作不应保持对上下文的引用。您应该在单独的层中运行任务,然后更新 viewModel 或保留片段中的必要字段。

于 2019-08-23T17:16:24.787 回答
0

静态变量与类的生命周期相关联。一旦活动被破坏,该静态变量也将被清理。

如果您仍想访问该变量,您有 2 个选项:-

  1. 覆盖 onSaveInstanceState 并保存所需的变量并在 onRestoreInstanceState 中恢复它
  2. 将变量存储在 Application 类中并随时随地访问它。
于 2019-08-22T09:33:06.093 回答
0

只要您不从最近的应用程序中清除它们,即使您按后退按钮关闭应用程序,它们也会保留。证明:好吧,我已经测试过它,您也可以很容易;)。

于 2019-02-12T19:43:57.480 回答
0

只要加载类,静态变量的值就会一直存在 - 它与 Activity 生命周期几乎无关(onCreate,...,onDestroy)

第一次从代码访问一个类时,它会被加载,然后直到有理由卸载它才会消失。

如果您的应用程序完全从内存中删除,Android 将卸载一个类 - 通过任务杀手或当您的应用程序不再处于活动状态且内存不足时。

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

于 2019-08-23T01:58:37.467 回答
0

是的,您在其中设置的值即使在活动关闭后仍然保持不变,但在应用程序关闭后不会保持不变。

于 2019-08-24T00:01:19.397 回答
0

我真的很惊讶没有人能够找到参考。它就在维基百科上:

...静态变量是“静态”分配的变量,这意味着它的生命周期(或“范围”)是程序的整个运行。这与寿命较短的自动变量不同,后者的存储是在调用堆栈上分配和释放的;与对象相反,对象的存储在堆内存中动态分配和释放。

此定义适用于通用编程语言。但是可以作为参考Android。但是,在面向对象的编程语言中:

面向对象编程中,还有静态成员变量的概念,它是静态定义类的“类变量”,即给定类的一个成员变量,在所有实例(对象)之间共享,并且可作为这些对象的成员变量访问。在类可以在运行时定义的语言中,动态定义类的类变量是在定义类时分配的,并且不是静态的。

这意味着在使用 Java 的 Android 中,静态变量的生命周期等于应用程序或使用它的实例的生命周期,如果该静态变量不是在运行时创建的。

于 2019-08-25T10:29:09.607 回答
0

我相信我终于找到了你的参考 -

垃圾收集器会自动清理未使用的对象。如果程序不再持有对它的引用,则该对象是未使用的。您可以通过将保存引用的变量设置为 null 来显式删除引用。

https://docs.oracle.com/javase/tutorial/java/javaOO/summaryclasses.html

需要明确的是,静态变量可能会保持初始化状态,从而防止类被正确地垃圾收集(也就是内存泄漏)。

于 2019-08-21T04:20:47.660 回答
0

Android 有一个空进程的概念,它表示如果用户经常使用你的应用程序,即使它的所有组件都被销毁(活动、服务和/或广播接收器),它也可能不会从内存中删除,在这种情况下,静态变量不会被彻底清除。

应用程序类是在组件之间共享一些临时变量的最佳方式,因为应用程序类将在应用程序启动时正确创建,并且一旦用户退出应用程序就会被清除。

参考:http ://skillgun.com/question/9849/android-provab/face-to-face-round/if-i-close-the-application-will-it-destroy-all-the-static-variables

于 2017-02-17T11:12:12.637 回答
-1

我最近为一个测验应用程序构建了一个背景音乐,我可以从任何活动中控制它,因为它是在一个静态类中。抓住的是音乐不断重新开始,所以我不得不将时间戳存储在 onPause 并传递给下一个活动以继续。静态类可能会被销毁,但为什么不在状态更改之前将其值存储在 sharedPreference 中。就像 onDestroy() 这样你就可以从任何地方初始化它。对于问题: 1 将值保存在 savedInstance 状态 2 将值保存在 onPause 或 onDestroy oncreate 状态的 sharedPreference 中。

于 2021-05-08T13:07:49.463 回答
-2

一旦我使用大量静态变量开发了应用程序,静态变量的问题是,一旦 android 内存不足,它会自动删除静态变量,如果您的视图与静态变量连接,它将不会显示或更糟糕的应用程序将崩溃。我建议使用共享首选项或其他方法来存储变量。

问题

  1. 如果您的 android 内存不足,则静态变量将从 ram 中删除,您必须重新初始化它们

  2. 如果您的视图附加到像 ArrayList 这样的静态变量到回收器视图,它将引发空指针异常等错误,因为您必须在每次初始化视图时检查平衡。

  3. 主要问题是您的变量太大,例如带有图像的 ArrayList,有时它可能会出现内存不足异常

于 2019-08-20T08:04:08.107 回答
-2

静态变量或静态块不与对象关联。这些是与对象无关的类级别变量。如果我们销毁对象,静态变量将不会销毁在同一个类中定义的对象。静态变量在内存中初始化一次。

所以当我们关闭应用程序对象时会破坏但静态变量不会破坏。但是当我们清除应用程序时,类销毁和静态变量也是如此。在这种情况下,由于可用内存空间导致静态变量破坏,有时 android 会杀死类。

于 2017-05-26T12:31:34.613 回答