[原文]
FROM STACKOVERFLOW:
Just giving my 50 cents on the issue. Catching the exception is indeed one possibility, but the correct way to deal with the issue of an activity being killed by the system for its resources in background is a common problem in android and according to Google the solution for this is:
onPause() is where you deal with the user leaving your activity. Most importantly, any changes made by the user should at this point be committed (usually to the ContentProvider holding the data).
Emphasis is mine. But what this means is that the Android lifecycles are designed so that under normal conditions onPause
should be called as an Activity
or Fragment
is sent to the background. They hint at this in several of the android documentation pages:
As your activity enters the paused state, the system calls the onPause() method on your Activity, which allows you to stop ongoing actions that should not continue while paused (such as a video) or persist any information that should be permanently saved in case the user continues to leave your app. If the user returns to your activity from the paused state, the system resumes it and calls the onResume() method.
Note: When your activity receives a call to onPause(), it may be an indication that the activity will be paused for a moment and the user may return focus to your activity. However, it's usually the first indication that the user is leaving your activity.
But the resource that could most likely help you are these two:
http://developer.android.com/training/basics/activity-lifecycle/stopping.html
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
What's probably happening with your lost resources is this:
When your activity receives a call to the onStop() method, it's no longer visible and should release almost all resources that aren't needed while the user is not using it. Once your activity is stopped, the system might destroy the instance if it needs to recover system memory. ... By default, the system uses the Bundle instance state to save information about each View object in your activity layout (such as the text value entered into an EditText object). So, if your activity instance is destroyed and recreated, the state of the layout is restored to its previous state with no code required by you. However, your activity might have more state information that you'd like to restore, such as member variables that track the user's progress in the activity.
Note: In order for the Android system to restore the state of the views in your activity, each view must have a unique ID, supplied by the android:id attribute.
To save additional data about the activity state, you must override the onSaveInstanceState() callback method. The system calls this method when the user is leaving your activity and passes it the Bundle object that will be saved in the event that your activity is destroyed unexpectedly. If the system must recreate the activity instance later, it passes the same Bundle object to both the onRestoreInstanceState() and onCreate() methods.
The correct solution for this is to override and implement the lifecycle methods of the Activity / Fragment as needed.
Two examples given by Google:
1 static final String STATE_SCORE = "playerScore"; 2 static final String STATE_LEVEL = "playerLevel"; 3 ... 4 5 @Override 6 public void onSaveInstanceState(Bundle savedInstanceState) { 7 // Save the user's current game state 8 savedInstanceState.putInt(STATE_SCORE, mCurrentScore); 9 savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); 10 11 // Always call the superclass so it can save the view hierarchy state 12 super.onSaveInstanceState(savedInstanceState); 13 } 14 Caution: Always call the superclass implementation of onSaveInstanceState() so the default implementation can save the state of the view hierarchy.
And the reverse restore operation:
1 public void onRestoreInstanceState(Bundle savedInstanceState) { 2 // Always call the superclass so it can restore the view hierarchy 3 super.onRestoreInstanceState(savedInstanceState); 4 5 // Restore state members from saved instance 6 mCurrentScore = savedInstanceState.getInt(STATE_SCORE); 7 mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); 8 }
当activity被切到后台时,执行onStop,如果此时系统内存不足或当前应用占用内存较多,会导致后台activity部分memroy被释放,因而当后台activity再次回到前台时,执行onResume会使得部分应用需要的变量等无法找到。
解决方法是将必要的变量信息存储到Bundle中,同时在onResume时加载该信息。