Android 静态对象生命周期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1944369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android static object lifecycle
提问by d-man
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 ???
但是我担心如果内存不足,android 中的静态对象生命周期会被 android 删除静态对象吗???
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 ???
由于 android 支持多任务,如果用户切换到另一个应用程序,当用户回来时应用程序开始疯狂,静态对象在多任务时会被删除吗???任何的想法 ??并建议通过单例方法保存静态对象是更好的方法???
回答by Samuh
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.
让我们从一些背景开始:启动应用程序时会发生什么?
操作系统启动一个进程并为其分配一个唯一的进程ID并分配一个进程表。一个进程启动一个DVM(Dalvik VM)的实例;每个应用程序都在 DVM 内运行。
DVM 管理类加载、卸载、实例生命周期、GC 等。
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.
静态变量的生命周期:当类被JVM 加载时,静态变量开始存在,并在类卸载时消亡。
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
因此,如果您创建一个 android 应用程序并初始化一个静态变量,它将保留在 JVM 中,直到发生以下情况之一:
1. 类被卸载
2. JVM 关闭
3. 进程 终止
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:
您可以使用几行代码对此进行测试:
- print the uninitialized static in onCreate of your activity -> should print null
- initialize the static. print it -> value would be non null
- Hit the back button and go to home screen. Note: Home screen is another activity.
- Launch your activity again -> the static variable will be non-null
- Kill your application process from DDMS(stop button in the devices window).
- Restart your activity -> the static will have null value.
- 在您的活动的 onCreate 中打印未初始化的静态 -> 应该打印 null
- 初始化静态。打印它 -> 值将是非空的
- 点击后退按钮并转到主屏幕。注意:主屏幕是另一个活动。
- 再次启动您的活动 -> 静态变量将为非空
- 从 DDMS(设备窗口中的停止按钮)终止您的应用程序进程。
- 重新启动您的活动 -> 静态将具有空值。
Hope that helps.
希望有帮助。
回答by r1k0
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:
嗯,单例模式也是基于使用静态变量,所以实际上你会处于相同的位置。虽然静态方法在大多数情况下可能有效,但在某些情况下,当内存已满并且另一个活动在您的应用程序移动到其下一个屏幕之前占据前台时,您的活动进程可能会被终止并且您会丢失静态值。然而,Android 提供了一些在状态之间保持值或传输它们的选项,例如:
- 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.
- 使用 Intent,您可以将搜索条件从一个活动传递到另一个活动(类似于 Web http 请求)
- 使用应用程序首选项,您可以保存值并在需要它们的活动中检索它们
- 使用 sqlite 数据库,您可以将它们保存在表中并稍后检索它们
- 如果您只需要保存活动状态,以便在重新启动时,字段将填充其先前选择的值,您可以实现 onSaveInstanceState() 活动方法 - 请注意,不建议在活动之间进行状态持久化。
You can get some code examples of the usage of preferences, intents and the sqlite database by looking at the aegis-shield source code treein google code or in other open source Android applications.
您可以通过查看google code 或其他开源 Android 应用程序中的aegis-shield 源代码树来获得一些使用首选项、意图和 sqlite 数据库的代码示例。
回答by Rick77
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:
经过一些研究,结果证明使用 Application 来存储单例并不是一个好主意,除非您准备重新创建它:
Don't store data in the application object
so while the accepted answeris 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.
正如上面的链接所暗示的那样,如果您真的想坚持使用该模型,则需要准备好检查 null 并在可能的情况下重新创建数据。
回答by eric.mcgregor
@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.
@r1k0 就在这里。将数据存储在类的静态字段中不会在应用程序进程终止和重新启动时自行持久化。当 Android 需要内存时,它会定期终止进程(正在运行的应用程序)。
Per the Android doc: Activity state and ejection from memory,
根据 Android 文档:活动状态和从内存中弹出,
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.
您可以使用以下方法保存和恢复原语以及 Serializable 和 Parcelable 对象的状态。这些在正常的活动生命周期中被自动调用。
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.
所以,如果你有一个只有静态变量的类,你可以在 onSaveInstanceState() 中保存每个字段的状态,并在 onRestoreInstanceState() 中恢复它们。当 Android 杀死您的应用程序正在运行的进程时,您的变量的状态将被保存,当 Android 恢复您的应用程序时,这些值将在内存中恢复为与以前相同的状态。