Android 静态对象生命周期

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

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

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

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

41637 次浏览

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.

Hope that helps.

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.

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.

@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.