Android静态对象生命周期

发布于 2024-08-15 15:08:58 字数 288 浏览 1 评论 0原文

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

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

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

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

I am creating event search application, we set search criteria from one screen populate in another screen then user can edit search criteria from 3rd screen and goes to 4th screen.

To achieve above task i am using static object which remember the values around the application and i don't need to do any thing extra.

But i am afraid if about static object life cycle in android if low memory found android delete static objects ???

As android supports multi tasking, if user switches to another application and when user comes back application start acting crazy, does static object get removed when it multi task ??? any idea ?? and also suggest holding static object via singleton method is better approach ???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

俯瞰星空 2024-08-22 15:08:58

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

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

因此,如果您创建一个 Android 应用程序并初始化一个静态变量,它将保留在 JVM 中,直到发生以下情况之一:

  1. 类被卸载
  2. JVM 关闭
  3. 进程终止

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

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

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

Lets start with a bit of background: What happens when you start an application?
The OS starts a process and assigns it a unique process id and allocates a process table.A process start an instance of DVM(Dalvik VM); Each application runs inside a DVM.
A DVM manages class loading unloading, instance lifecycle, GC etc.

Lifetime of a static variable: A static variable comes into existence when a class is loaded by the JVM and dies when the class is unloaded.

So if you create an android application and initialize a static variable, it will remain in the JVM until one of the following happens:

  1. the class is unloaded
  2. the JVM shuts down
  3. the process dies

Note that the value of the static variable will persist when you switch to a different activity of another application and none of the above three happens. Should any of the above three happen the static will lose its value.

You can test this with a few lines of code:

  1. print the uninitialized static in onCreate of your activity -> should print null
  2. initialize the static. print it -> value would be non null
  3. Hit the back button and go to home screen. Note: Home screen is another activity.
  4. Launch your activity again -> the static variable will be non-null
  5. Kill your application process from DDMS(stop button in the devices window).
  6. Restart your activity -> the static will have null value.
挽容 2024-08-22 15:08:58

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

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

您可以通过查看 aegis-shield 源代码树

Well, the Singleton pattern is also based on using static variables so actually you would be in the same position. While the static approach may work most of the times, it may happen that in some cases when memory is full and another activity takes the foreground before your application moves to its next screen, your activity's process could be killed and you lose the static values.
However Android offers a few options of persisting values between states or transmitting them such as:

  • using an Intent, you could pass along
    your search criteria from activity to
    activity (similar to a web http
    request)
  • using application preferences, you
    could save the values and retrieve
    them in the activity that needs them
  • using the sqlite database you can
    persist them in a table and retrieve
    them later
  • if you need to just save activity
    state so that on restart, the fields
    get filled with their previously
    selected values, you can implement
    the onSaveInstanceState() activity
    method - note that this is not
    recommended for between activities
    persistance of states.

You can get some code examples of the usage of preferences, intents and the sqlite database by looking at the aegis-shield source code tree in google code or in other open source Android applications.

墨落成白 2024-08-22 15:08:58

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

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

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

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

After some research, it turns out that using Application to store singletons is not that great of an idea, unless you are ready to recreate it:

Don't store data in the application object

so while the accepted answer is technically correct, it doesn't provide all information.

As the link above suggests, if you really want to stick with that model, you need to be ready to check for null and recreate the data, if possible.

热鲨 2024-08-22 15:08:58

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

根据 Android 文档:Activity 状态和从内存中弹出,

系统永远不会直接终止活动。相反,它杀死了
Activity运行的过程,破坏的不仅仅是Activity
但进程中运行的其他所有内容也是如此。

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

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

因此,如果您有一个仅包含静态变量的类,则可以在 onSaveInstanceState() 中保存每个字段的状态,并在 onRestoreInstanceState() 中恢复它们。当 Android 终止您的应用程序正在运行的进程时,变量的状态将被保存,当 Android 恢复您的应用程序时,这些值将以与之前相同的状态恢复到内存中。

@r1k0 is right here. Storing data in static fields of a class will not persist on its own across application process kills and restarts. Android routinely kills processes (running apps) when it needs memory.

Per the Android doc: Activity state and ejection from memory,

The system never kills an activity directly. Instead, it kills the
process in which the activity runs, destroying not only the activity
but everything else running in the process, as well.

You can save and restore the state of primitives as well Serializable and Parcelable objects using the methods below. These are automatically called during the normal activity lifecycle.

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

So, if you have a class that has only static variables, you can save the state of each field in onSaveInstanceState() and restore them in onRestoreInstanceState(). When Android kills the process that your app is running in, the state of your variables will be saved, and when Android restores your app, the values will be restored in memory in the same state as before.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文