Android中静态变量的生命周期

时间:2013-07-27 17:16:02

标签: java android static

当我在主活动中声明并初始化变量为静态并且活动被销毁时。我还可以访问变量的内容吗?

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

14 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:4)

  

我还可以访问变量的内容吗?

假设“被破坏”是指用户按下BACK,是的。

静态数据成员在整个过程中都会存在。

  

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

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

答案 2 :(得分:2)

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

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

对于您的情况: ViewModel体系结构组件可在配置更改中保留对象。您可以使用它,但是仍然需要注意上下文泄漏。另一个选择是使用没有UI的片段。您在片段中调用函数setRetainInstance(true),系统将在配置更改中保留该片段。该片段保留您的数据,配置更改发生后,您可以通过片段管理器获取此片段。实际上,后者是ViewModel的基础机制。对于诸如AsyncTask之类的多线程情况,在单独线程中运行的操作不应保留对上下文的引用。您应该在单独的图层中运行任务,然后在viewModel或保留的片段中更新必要的字段。

答案 3 :(得分:2)

静态变量与类本身联系在一起。只要该类在内存中,变量就会被保留。

类生活在称为Permanent Generation的内存空间中时,很少会收集垃圾(您可以在https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html上找到有关世代GC的更多信息)。

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

方向更改不会清除静态变量,但是,如果这是您的目标,那么使用静态变量就不太合适。您可以使用setRetainInstance或类似方法来保持方向改变时的实例状态(有关答案,请参见Android: how do I prevent class variables being cleared on orientation change

答案 4 :(得分:0)

  

Android的概念为empty process,表示您的应用可能没有   如果用户经常使用即使从内存中删除即可   其所有组件都被销毁(活动,服务和/或   广播接收器),在这种情况下静态变量不会   彻底清除了。

     

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

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

答案 5 :(得分:0)

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

所以当我们关闭app对象时会破坏但静态变量不会被破坏。但是当我们清除app然后类破坏和静态变量也。有时android杀死类由于空闲内存空间,在这种情况下静态变量destroy。

答案 6 :(得分:0)

即使您没有通过后退按钮关闭应用程序,只要您不从最近的应用程序中清除它们,它们就会保留。证明:我已经对其进行了测试,这很容易;)。

答案 7 :(得分:0)

我相信我终于找到了您的参考资料-

  

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

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

需要明确的是,静态变量可能会保持初始化状态,从而无法正确地垃圾分类收集类(又称内存泄漏)。

答案 8 :(得分:0)

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

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

  1. 覆盖onSaveInstanceState并保存所需的变量,然后将其还原到onRestoreInstanceState
  2. 将变量存储在Application类中并在任何地方访问 随时。

答案 9 :(得分:0)

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

第一次使用代码访问类时,它将被加载,直到有理由将其卸载后,它才会消失。

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

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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

我真的很惊讶,没有人能找到参考。就在Wikipedia上:

  

...静态variableallocated“静态”的变量,这意味着其生存期(或“范围”)是程序的整个运行过程。这与寿命较短的automatic variables形成对比,后者的存储空间为stack allocated,并被释放在call stack上;与objects相比,dynamically allocated的存储空间为heap memory,并在object-oriented programming中释放。

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

  

static member variable中,还有"class variable"的概念,它是静态定义的类的member variable,即给定类的instances在所有{{3}}(对象)之间共享,并且可以作为这些对象的成员变量进行访问。动态定义类的类变量(在可以在运行时定义类的语言中)是在定义类时分配的,并且不是静态的。

这意味着在使用Java的Android中,静态变量的生存期等于应用程序或使用它的实例的生存期(如果未在运行时创建该静态变量)

答案 12 :(得分:-1)

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

答案 13 :(得分:-2)

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

问题

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

  2. 如果视图附加到静态变量(如ArrayList)到回收器视图,则它将引发诸如空指针异常之类的错误,因此每次初始化视图时都必须检查平衡。

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