相信大家对Activity的生命周期一定不会感到陌生,如果还有不清楚的童鞋,可以参考一下这篇文章:《基础总结篇之一:Activity生命周期》。其实,只要理解了Activity的几种状态,对生命周期就能快速理解。这篇文章主要参考官方的解释以及自己的思考总结而成。 以下这个图大家肯定很陌生:
图1. A simplified illustration of the Activity lifecycle, expressed as a step pyramid
如图1,按照官方的形象比喻,在一个activity的生命周期,系统调用一系列类似于金字塔台阶的生命周期方法。每一个调用方法都是金字塔的一个台阶。系统创建一个新的activity实例时,每个回调方法将activity状态向着金字塔顶端移动。那么问题来了?哪个状态是activity的金字塔顶端?答案是Resumed状态,当activity运行在前台,可以和用户交互的时候。
实际上,在activity的众多状态中,只有三种是可以长久停留的(算上Destroyed的话应该是四种),分别是:
Resumed:有时又叫运行状态,activity运行在前台,用户可以和它交互。
Paused:在这种状态中,activity被其它的activity局部遮蔽-其它在前台的activity是半透明的或者没有覆盖全部的屏幕。暂停住的activity不能接受用户的输入也不能执行任何代码。(In this state, the activity is partially obscured by another activity—the other activity that’s in the foreground is semi-transparent or doesn’t cover the entire screen. The paused activity does not receive user input and cannot execute any code.)
——理解这句话对于理解activity生命周期显得非常重要,如在activityA中启动一个对话框activity Dialog,Dialog没有遮蔽activityA的全部界面,这时,activityA就走到onPause(),不会再去调用onStop()。
Stopped:在这种状态中,activity已经完全被遮挡,对用户来说已经不可见,可以认为已经退到后台。当处于Stopped状态时,activity实例和所有的状态信息将被保留,但它不能运行任何代码。(In this state, the activity is completely hidden and not visible to the user; it is considered to be in the background. While stopped, the activity instance and all its state information such as member variables is retained, but it cannot execute any code.)
——这就能理解当activityA跳转到activityB(activitB将activityA界面完全覆盖)、来电话、按power或者home键会退到后台时,activityA依次会调用onPause()->onStop()。因为这时activityA界面已经完全被遮挡,对用户来说已经不可见。理解这几种状态可以加深对生命周期的印象,重要点在activity可见不可见以及被遮挡。
我们应该在activity的各个方法中都做些什么工作呢?官方同样给出了建议。
You must implement the onCreate() method to perform basic application startup logic that should happen only once for the entire life of the activity. For example, your implementation of onCreate() should define the user interface and possibly instantiate some class-scope variables.
例如,下面的例子在onCreate()中主要为activity执行了一些基础的建立工作。比如,声明用户的界面(setContentView),定义成员变量(mTextView),构建一些UI (ActionBar actionBar)等。
TextView mTextView; // Member variable for text view in the layout
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the user interface layout for this Activity
// The layout file is defined in the project res/layout/main_activity.xml file
setContentView(R.layout.main_activity);
// Initialize member TextView so we can manipulate it later
mTextView = (TextView) findViewById(R.id.text_message);
// Make sure we're running on Honeycomb or higher to use ActionBar APIs
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// For the main activity, make sure the app icon in the action bar
// does not behave as a button
ActionBar actionBar = getActionBar();
actionBar.setHomeButtonEnabled(false);
}
}
The system calls this method on your activity as the final signal that your activity instance is being completely removed from the system memory.
如果你在onCreate()中创建了一个后台线程的话,你最好在onDestroy()中把它杀掉。
When the system calls onPause() for your activity, it technically means your activity is still partially visible, but most often is an indication that the user is leaving the activity and it will soon enter the Stopped state. You should usually use the onPause() callback to:
• Stop animations or other ongoing actions that could consume CPU.
• Commit unsaved changes, but only if users expect such changes to be permanently saved when they leave (such as a draft email).
• Release system resources, such as broadcast receivers, handles to sensors (like GPS), or any resources that may affect battery life while your activity is paused and the user does not need them.
For example, if your application uses the Camera, the onPause() method is a good place to release it.
@Override
public void onPause() {
super.onPause(); // Always call the superclass method first
// Release the Camera because we don't need it when paused
// and other activities might need to use it.
if (mCamera != null) {
mCamera.release()
mCamera = null;
}
}
Generally, you should not use onPause() to store user changes (such as personal information entered into a form) to permanent storage. The only time you should persist user changes to permanent storage withinonPause() is when you’re certain users expect the changes to be auto-saved (such as when drafting an email).
(Email确实是一个比较好的例子,老外写文档很用心啊!)
However, you should avoid performing CPU-intensive work during onPause(), such as writing to a database, because it can slow the visible transition to the next activity (you should instead perform heavy-load shutdown operations during onStop()).
(应该避免在onPause中去写数据库,因为这样会将显示下一个activity的操作减慢),应该把这些繁重的操作放在onStop中去。)
When the user resumes your activity from the Paused state, the system calls the onResume() method.
Be aware that the system calls this method every time your activity comes into the foreground, including when it’s created for the first time. As such, you should implement onResume() to initialize components that you release during onPause() and perform any other initializations that must occur each time the activity enters the Resumed state (such as begin animations and initialize components only used while the activity has user focus).
The following example of onResume() is the counterpart to the onPause() example above, so it initializes the camera that’s released when the activity pauses.
@Override
public void onResume() {
super.onResume(); // Always call the superclass method first
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera init
}
}
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. In extreme cases, the system might simply kill your app process without calling the activity’s final onDestroy() callback, so it’s important you use onStop() to release resources that might leak memory.
(在某些极端的情况下(内存不足),系统可能会会简单的杀死你的APP进程而不去调用onDestroy()回调方法,所以在onStop()中释放可能造成内存泄露的资源)。
Although the onPause() method is called before onStop(), you should use onStop() to perform larger, more CPU intensive shut-down operations, such as writing information to a database.
For example, here’s an implementation of onStop() that saves the contents of a draft note to persistent storage:
@Override
protected void onStop() {
super.onStop(); // Always call the superclass method first
// Save the note's current draft, because the activity is stopping
// and we want to be sure the current note progress isn't lost.
ContentValues values = new ContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
getContentResolver().update(
mUri, // The URI for the note to update.
values, // The map of column names and new values to apply to them.
null, // No SELECT criteria are used.
null // No WHERE columns are used.
);
}
It happens every time your activity becomes visible (whether being restarted or created for the first time).
(它在activity变为可见时就会被调用,不管是第一次或者restart的时候,正因为如此,官方推荐重点调用onStart()方法!)
It’s uncommon that an app needs to use onRestart() to restore the activity’s state, so there aren’t any guidelines for this method that apply to the general population of apps. However, because your onStop()method should essentially clean up all your activity’s resources, you’ll need to re-instantiate them when the activity restarts. Yet, you also need to instantiate them when your activity is created for the first time (when there’s no existing instance of the activity). For this reason, you should usually use the onStart() callback method as the counterpart to the onStop() method, because the system calls onStart() both when it creates your activity and when it restarts the activity from the stopped state.
For example, because the user might have been away from your app for a long time before coming back it, theonStart() method is a good place to verify that required system features are enabled:
@Override
protected void onStart() {
super.onStart(); // Always call the superclass method first
// The activity is either being restarted or started for the first time
// so this is where we should make sure that GPS is enabled
LocationManager locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!gpsEnabled) {
// Create a dialog here that requests the user to enable GPS, and use an intent
// with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
// to take the user to the Settings screen to enable GPS when they click "OK"
}
}
@Override
protected void onRestart() {
super.onRestart(); // Always call the superclass method first
// Activity being restarted from stopped state
}
When the system destroys your activity, it calls the onDestroy() method for your Activity. Because you should generally have released most of your resources with onStop(), by the time you receive a call to onDestroy(), there’s not much that most apps need to do. This method is your last chance to clean out resources that could lead to a memory leak, so you should be sure that additional threads are destroyed and other long-running actions like method tracing are also stopped.
(总结:尽量在这个方法中减少操作,将释放资源,停止线程等的操作放在onStop()中)。
When your activity is recreated after it was previously destroyed, you can recover your saved state from the Bundle that the system passes your activity. Both the onCreate() and onRestoreInstanceState() callback methods receive the same Bundle that contains the instance state information.
Because the onCreate() method is called whether the system is creating a new instance of your activity or recreating a previous one, you must check whether the state Bundle is null before you attempt to read it. If it is null, then the system is creating a new instance of the activity, instead of restoring a previous one that was destroyed.
For example, here’s how you can restore some state data in onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance
}
...
}
Instead of restoring the state during onCreate() you may choose to implement onRestoreInstanceState(), which the system calls after the onStart() method. The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null:
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
总结:在onCreate()中也可以恢复状态,需要判断是否为空。在回调接口onRestoreInstanceState()中却不需要。
参考文章:
http://developer.android.com/training/basics/activity-lifecycle/index.html