路漫漫其修遠兮,吾將上下而求索。---屈原《離騷》
可能很多人會感覺Activity很簡單,但是經歷了半年的android開發,我發現我對Activity的的理解還是比較淺顯的,其實Activity并沒有我們想象的那么簡單今天花了一個下午學習了Activity的生命周期,為以后忘記后迅速回顧,做準備。
**一、首先看下官網給出activity的生命周期圖**

我們可以從圖中分析它的執行過程:
1.啟動Activity:系統會首先調用onCreate方法,然后調用onStart方法,最后調用onResume()方法。此時Activity進入運行狀態
2.當前Activity被其他Activity覆蓋或處于鎖屏狀態:系統會調用onPause方法,然后調用onStop方法,此時Activity處于停滯狀態。
3.當前Activity由覆蓋狀態回到前臺或解鎖屏:系統會調用onRestart方法,然后調用onStart方法,最后調用onResume方法,再次進入運行狀態。
4.當前Activity跳轉到新的Activity界面或Home鍵回到主屏,退到后臺:系統會先調用onPause方法,然后調用onStop方法進入停滯狀態
5.用戶后退回到此Activity:系統會先調用onRestart()方法,然后調用onStart方法,最后調用onResume方法,再次進入運行狀態
6.當前Activity處于被覆蓋狀態或者后臺不可見狀態,即第二和第四步,系統內存不足,殺死當前Activity,而后用戶退回當前Activity:再次調用onCreate方法、onStart方法、onResume方法,進入運行狀態。
7.用戶退出當前Activity:系統會調用onPause方法,然后調用onStop方法最后調用onDestroy方法,結束當前Activity
以上的Activity方法的生命周期是很簡單的,但是任何簡單的東西,只有我們通過實例驗證才能理解的更加透徹,記憶更加深刻,
**二、實例分析**
實例代碼:
~~~
package com.example.activitypractice;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private Button btn_jump;
private String saveData= "存放的數據" ;
//Activity創建時調用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main);
btn_jump=(Button) findViewById(R.id. btn_jump);
btn_jump.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
Intent intent= new Intent(MainActivity.this,JumpToActivity.class );
startActivity(intent);
}
});
Log. i(TAG,"執行了onCreate方法" );
}
//Activity創建或者從后臺重新回到前臺時被調用
@Override
protected void onStart() {
super.onStart();
Log. i(TAG,"執行了onStart方法" );
}
//Activity從后臺重新回到前臺時被調用
@Override
protected void onRestart() {
super.onRestart();
Log. i(TAG,"執行了onRestart方法" );
}
//Activity創建或者從被覆蓋、后臺重新回到前臺時被調用
@Override
protected void onResume() {
super.onResume();
Log. i(TAG,"執行了onResume方法" );
}
//Activity被覆蓋到下面或者鎖屏時被調用
@Override
protected void onPause() {
super.onPause();
Log. i(TAG,"執行了onPause方法" );
}
//退出當前Activity或者跳轉到新Activity時被調用
@Override
protected void onStop() {
super.onStop();
Log. i(TAG,"執行了onStop方法" );
}
//退出當前Activity時被調用,調用之后Activity就結束了
@Override
protected void onDestroy() {
super.onDestroy();
Log. i(TAG,"執行了onDestroy方法" );
}
//Activity窗口獲得或失去焦點時被調用,在onResume之后或onPause之后
/* @Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.i(TAG, "onWindowFocusChanged called.");
} */
/**
* Activity被系統殺死時被調用.
* 例如:屏幕方向改變時,Activity被銷毀再重建;當前Activity處于后臺,系統資源緊張將其殺死.
* 另外,當跳轉到其他Activity或者按Home鍵回到主屏時該方法也會被調用,系統是為了保存當前View組件的狀態.
* 在onPause之前被調用.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString( "key", saveData);
Log. i(TAG, "onSaveInstanceState called.put saveData: " + saveData );
super.onSaveInstanceState(outState);
}
/**
* Activity被系統殺死后再重建時被調用.
* 例如:屏幕方向改變時,Activity被銷毀再重建;當前Activity處于后臺,系統資源緊張將其殺死,用戶又啟動該Activity.
* 這兩種情況下onRestoreInstanceState都會被調用,在onStart之后.
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
String getData = savedInstanceState.getString( "key");
Log. i(TAG, "onRestoreInstacedState called.getData: "+getData);
super.onRestoreInstanceState(savedInstanceState);
}
}
~~~
在上面的例子中我們可以看到還有三個不是特別常見的方法,onWindowFocusChanged、onSaveInstanceState、onRestoreInstanceState方法這三個方法我們用的比較少下面也來說說它們的用法:
(1)onWindowFocusChanaged方法
在Activity窗口獲得或失去焦點時調用,例如創建時首次展示在用戶面前、當Activity被其它Activity所覆蓋、Activity退到后臺、用戶退出當前Activity,這幾種條件都會調用onWindowFocusChanaged,并且當Activity被創建時是在onResume之后被調用,當Activity被覆蓋或者退到后臺或當前Activity退出時它是在onPause之后被調用的,如下圖Activity啟動之后被其它的activity覆蓋(點擊我們的跳轉按鈕)打印的日志

這個方法在很多場合下還是很有用的,例如程序啟動時想要獲取組件的尺寸大小,在onCreate中是無法取到的因為Window對象還沒有創建完,這時候我們就需要在onWindwosFocusChanaged里獲取,這也是我們常用的方法。
(2)onSaveInstanceState:
?1.在Activity被覆蓋或者退到后臺之后,系統資源不足,將其殺死,此方法會被調用;
?2.在用戶改變屏幕方向時此方法會被調用;
?3.在當前Activity跳轉到其他Activity或者按Home鍵回到主屏,自身退到后臺時,此方法會被調用。
第一種情況我們無法保證什么時候發生,系統根據資源的緊張程度去調度;第二種是屏幕翻轉方向時,系統先銷毀當前Activity,然后再重建一個新的,調用此方法時,我們可以保存一些臨時數據,例如:當豎屏時加載一個進度條,切換到橫屏時如果不保存當前加載到多少橫屏時會重0開始,保存后就可以繼續加載,第三種情況系統調用此方法是為了保存當前窗口各個View組件的狀態。onSaveInstanceState的調用順序是在onPause之后,如下圖是在跳轉到其它的Activity所執行的方法
我們從圖中可以看出onSaveInstanceState方法是在onPause方法中執行的
(3)onRestoreInstanceState
1.在Activity被覆蓋或是退居后臺之后,系統資源不足將其殺死,然后又回到了此Activity,此方法會被調用
2.在用戶改變屏幕方向時,重建的過程中,此方法會被調用。我們可以重寫此方法,以便恢復一些臨時數據。onRestoreInstanceState的調用順序是在onStart方法之后。

之后我們來結合上面的例子來一 一看看Activity的生命周期在各種的情況下的變化
1.啟動Activity:

啟動Activity:系統會首先調用onCreate方法,然后調用onStart方法,最后調用onResume()方法。此時Activity進入運行狀態
2.在1跳轉到其他的Activity,或按Home鍵

系統會先調用onPause方法,然后調用 onSaveInstanceState方法,然后調用onStop方法進入停滯狀態
3.從后臺回到前臺

系統會先調用onRestart方法,然后調用onStart方法,然后調用onResume方法
4.修改在AndroidMainfest.xml中的配置,將android:theme屬性設置為@android:style/Theme.Dialog,然后再點擊跳轉按鈕,然后JumpToActivity覆蓋到LifeCycleActivity之上了,

此時調用的方法為:onPause和onSaveInstanceState,我們注意到,此時MainActivity的onPause方法被調用,并沒有執行onStop方法,因為此時的MainActivity沒有退居到后臺只是被覆蓋或被鎖屏;onSaveInstanceState會在onPause之后被調用
5.在4的基礎上按回退鍵MainActivity從被覆蓋回到前面

此時執行onResume方法
6.退出

系統調用onPause、onStop、onDestroy方法。
不知道大家有沒有發現在上面的所有的日志中并沒有執行onRestoreInstanceState方法,為什么沒有執行它呢沒有滿足它執行的條件,從上面onRestoreInstanceState執行的條件我們發現第一種是不可預測的,但是第二種(即改變屏幕方向)的話我們可以模擬的
**三、Activity屏幕方向的知識**
我們可以為一個Activity指定一個特定的方向,指定之后即使轉動屏幕方向,顯示方向也不會跟著轉動
1.指定為豎屏:在AndroidManifest.xml文件中對指定的Activity設置android:screenOrientation:="portrait",
或者在onCreate方法中指定代碼為:
setRequestOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);就指定為了豎屏
2.指定為橫屏:在AndroidManifest.xml文件中對指定的Activity設置android:screenOrientation:="landscape",
或者在onCreate方法中指定代碼為:
setRequestOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);就指定為了豎屏
在開發應用的過程中,為應用中的Activity設置特定的方向是經常用到的方法,可以為我們省去很多麻煩,但是我為了讓onRestoreInstanceState方法執行采用的是不固定屏幕的顯示方向我們對上面的代碼稍作修改加上onConfigurationChanged方法
現在源碼如下:
~~~
package com.example.activitypractice;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private Button btn_jump;
private String saveData= "存放的數據" ;
//Activity創建時調用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main);
btn_jump=(Button) findViewById(R.id. btn_jump);
btn_jump.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
Intent intent= new Intent(MainActivity.this,JumpToActivity.class );
startActivity(intent);
}
});
Log. i(TAG,"執行了onCreate方法" );
}
//Activity創建或者從后臺重新回到前臺時被調用
@Override
protected void onStart() {
super.onStart();
Log. i(TAG,"執行了onStart方法" );
}
//Activity從后臺重新回到前臺時被調用
@Override
protected void onRestart() {
super.onRestart();
Log. i(TAG,"執行了onRestart方法" );
}
//Activity創建或者從被覆蓋、后臺重新回到前臺時被調用
@Override
protected void onResume() {
super.onResume();
Log. i(TAG,"執行了onResume方法" );
}
//Activity被覆蓋到下面或者鎖屏時被調用
@Override
protected void onPause() {
super.onPause();
Log. i(TAG,"執行了onPause方法" );
}
//退出當前Activity或者跳轉到新Activity時被調用
@Override
protected void onStop() {
super.onStop();
Log. i(TAG,"執行了onStop方法" );
}
//退出當前Activity時被調用,調用之后Activity就結束了
@Override
protected void onDestroy() {
super.onDestroy();
Log. i(TAG,"執行了onDestroy方法" );
}
/**
* Activity被系統殺死時被調用.
* 例如:屏幕方向改變時,Activity被銷毀再重建;當前Activity處于后臺,系統資源緊張將其殺死.
* 另外,當跳轉到其他Activity或者按Home鍵回到主屏時該方法也會被調用,系統是為了保存當前View組件的狀態.
* 在onPause之前被調用.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString( "key", saveData);
Log. i(TAG, "onSaveInstanceState called.put saveData: " + saveData );
super.onSaveInstanceState(outState);
}
/**
* Activity被系統殺死后再重建時被調用.
* 例如:屏幕方向改變時,Activity被銷毀再重建;當前Activity處于后臺,系統資源緊張將其殺死,用戶又啟動該Activity.
* 這兩種情況下onRestoreInstanceState都會被調用,在onStart之后.
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
String getData = savedInstanceState.getString( "key");
Log. i(TAG, "onRestoreInstacedState called.getData: "+getData);
super.onRestoreInstanceState(savedInstanceState);
}
//當指定了android:configChanges="orientation"后,方向改變時onConfigurationChanged被調用,并且activity不再銷毀重建
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
switch (newConfig. orientation) {
case Configuration. ORIENTATION_PORTRAIT://豎屏
Log. i(TAG,"豎屏" );
setContentView(R.layout. portrait);
break;
case Configuration. ORIENTATION_LANDSCAPE://橫屏
Log. i(TAG,"橫屏" );
setContentView(R.layout. landscap);
default:
break;
}
}
}
~~~
需要注意的是我們必須在手機上設置(注意:要在設置中設置自動旋轉屏幕我用的三星的測試機是在設定-->我的設備-->顯示 ?在"顯示"里有"自動旋轉屏幕"選項)自動旋轉屏幕才可以
然后當我們旋轉屏幕時,我們會看到Activity首先會銷毀然后重建,系統會調用onSaveInstanceState方法并在Bundle對象中保存了一個臨時的數據,當Activity銷毀后再重建時調用onRestoreInstancedState方法我們從中可以把保存的數據取出來日志如下:

但是Activity銷毀后再重建,這有時候并不是我們想要的,那么我們應該怎樣避免這種情況呢?這是我們應該在清單文件中對應的Activity中配置android:configChanges="orientation"然后我們再旋轉屏幕

每次在旋轉的時候都調用了onConfigurationChanged方法,并且Activity沒有了銷毀重建的過程
在上面的配置過程中我們需要注意幾點:
1.如果在Activity中配置了android:screenOrientation屬性,則會使android:configChanges="orientation"失效。
2.在配置android:configChanges時需要注意:如果是Android 4.0,則是"orientation|keyboardHidden|screenSize",如果是
? 4.0之前的版本android:configChanges="orientation|keyboardHidden"
[關于android:configChanges配置時需注意的事項見此鏈接](http://blog.csdn.net/dmk877/article/details/45056027)