作者: "@gzdaijie" 本文為作者原創,轉載請註明出處:http://www.cnblogs.com/gzdaijie/p/5255084.html 目錄 1.Activity生命周期 1.1 Activity生命周期簡介與測試 1.2 設備旋轉時的生命周期與數據恢復 1.3 Activit
作者:@gzdaijie
本文為作者原創,轉載請註明出處:http://www.cnblogs.com/gzdaijie/p/5255084.html
目錄
1.Activity生命周期
1.1 Activity生命周期簡介與測試
1.2 設備旋轉時的生命周期與數據恢復
1.3 Activity暫存與Activity記錄
2.Activity啟動模式
2.1 standard
2.2 singleTop
2.3 singleTask
2.4 singleInstance
1.Activity生命周期
接下來將介紹 Android Activity(四大組件之一) 的生命周期, 包含運行、暫停和停止三種狀態,onCreate、onStart、onResume、onPause、onStop、onDestroy六種系統調用方法。
1.1 Activity生命周期簡介與測試
如圖所示,Activity實例可以在生命周期狀態發生關鍵性轉換時完成某些工作。
- onCreate()
創建
,該方法是最常被覆蓋的方法,第一次創建實例時調用, 一般用來完成實例創建的初始化操作,包括實例化組件,設置監聽器,訪問外部模型數據等。- onStart()
開始
,當Activity處於可見狀態的時候就會調用onStart方法,包括創建完實例顯示,或者從其他活動切換到活動時調用。- onResume()
準備
,當Activity獲得用戶焦點時調用。- onPause
暫停
,當Activity準備調用或者恢復另一個活動時調用,失去焦點時,例如啟動一個Dialog調用。該方法可以釋放一些消耗CPU的資源,保存一些關鍵數據,但是執行速度要快,否則影響新的棧頂活動使用。- onStop
停止
,完全不可見時調用。例如成功啟動了另外一個活動,該活動離開棧頂不可見。啟動Dialog不會執行該方法。- onDestroy
銷毀
,這個方法在活動銷毀時調用。
// 可以使用以下方法進行測試。
public class MainActivity extends Activity {
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG,"Create");
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "Start");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "Resume");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "Pause");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "Stop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "Destroy");
}
}
1.2 設備旋轉時的生命周期與數據恢復
使用上面的日誌列印測試方法發現, 設備旋轉時生命周期如圖所示,即設備旋轉時,當前活動實例會被系統銷毀,然後創建一個新的實例。
因為旋轉設備會改變設備配置(device configuration),設備配置包括屏幕的方向、密度、尺寸、鍵盤類型、底座模式等,為匹配不同的設備,可以使用不同的佈局文件,這和Web開發中 針對不同寬度的屏幕選擇不同CSS樣式異曲同工,如何創建不同佈局適配不同配置設備不在本文討論之列。
設備旋轉時,臨時數據會丟失。例如你使用了一個變數記錄了用戶點擊了多少次按鈕,設備旋轉之後,Activity重新創建,這個變數就被初始化了,這裡可以使用Bundle
對象來恢復。保存數據可以覆蓋onSaveInstanceState()
方法。
例如下麵的代碼,按3次按鈕,旋轉屏幕後,將列印出saved currentPage:3 init mCurrentPage:0,點擊次數存在了Bundle對象中,併在onCreate()中獲取到。
/*
* onSaveInstanceState()通常在onPause、onStop、onDestroy前由系統調用
* onCreate()傳入的參數savedInstanceState可獲取保存的變數
*/
public class MainActivity extends Activity {
private static final String KEY = "currentPage";
private static final String TAG = "MainActivity";
private Integer mCurrentPage = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCurrentPage += 1;
}
});
if(savedInstanceState != null){
// 列印使用Bundle保存的currentPage信息
Log.d(TAG,"saved currentPage: " + savedInstanceState.getInt(KEY,0));
// 列印新建活動mCurrentPage的值,總為0
Log.d(TAG,"init mCurrentPage: " + mCurrentPage);
// ... update code
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// 使用key-value對的方式存儲臨時變數
outState.putInt(KEY, mCurrentPage);
}
}
1.3 Activity暫存與Activity記錄
當系統回收記憶體時,處於Pause、Stop狀態的Activity可能被銷毀,此時系統會調用onSaveInstanceState(),用戶數據被存儲在Bundle對象中,系統將Bundle對象放入Activity記錄,可以將這種狀態理解為Activity的暫存狀態(無實例有記錄)。
Activity暫存後,當前活動不復存在,Activity記錄可幫助用戶返回應用時活動的快速恢復,提供一個好的用戶體驗。但是當用戶按了後退鍵,系統會徹底銷毀當前活動,Activity記錄同時被清除,系統重啟也會被清除該記錄。
2.Activity啟動模式
2.1 standard(預設)
standard是活動預設的啟動模式,Android是使用返回棧來管理活動的,所謂棧就是先進後出,後進先出。該模式下,每啟動一個新的活動,就會在返回棧中入棧,並處於棧頂的位置(即用戶當前見到的活動)。系統不會 檢查該活動的實例已經在返回棧中存在,每次啟動都新建一個。當前返回棧為A->B(B為棧頂),新建活動B, 返回棧變為A->B->B。
2.2 singleTop
standard模式有時並不合理,比如活動實例已經在棧頂了,再次啟動時還需再創建一個實例, 這會造成資源的浪費。singleTop模式下,如果當前棧頂已經是該活動實例,則認為可以直接使用,而不再創建新的活動。當前返回棧為A->B(B為棧頂),新建活動B, 返回棧仍為A->B。
<!--AndroidManifest.xml-->
<!--設置方式,launchMode -->
<activity android:name=".MainActivity"
android:launchMode="singleTop"
android:label="AndroidDialog">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
2.3 singleTask
singleTop模式可以避免重覆創建棧頂活動的問題,但是如果啟動活動不在棧頂,而之前已經創建過,還是會重覆創建。例如A->B->C,當前已有三個活動A、B、C,C位於棧頂,再創建B,返回棧變為A->B->C->B(另一個實例)。singleTask模式可以讓返回棧中每個活動只存在一個實例,如果發現當前需要啟動活動已經在棧中,則直接使用,但是該活動之上的所有活動全部出棧;如沒有發現,則創建新的實例。例如A->B->C,如此時創建活動B,則返回棧變為A->B(B存在,使用B,C出棧);若此時創建活動D,則返回棧變為A->B->C->D
2.4 singleInstance
singleInstance模式是四種啟動模式中最複雜的,不同於上述三種模式,指定為singleInstance模式的活動會啟動一個新的返回棧來管理這個活動。例如當前有活動A、B、C,活動A、C為預設啟動模式,B指定為singleInstance模式,首先新建A,A活動頁面啟動B,B啟動C,此時的返回棧並不是A->B->C,而是存在2個返回棧,一個是A->C,另一個是B。此時按下BACK鍵返回,將從C返回到A,再按一次,A返回到B,按第三次,程式退出。即返回時,先清空棧A->C,再清空棧B。
singleInstance模式有什麼應用場景呢?例如當前程式中某個活動允許其他活動調用,如果想多個程式共用該活動的一個實例A,那麼每一個程式都有一個返回棧,若使用前3種模式,該活動入棧時必然創建新的實例,無法實現實例共用。singleInstance能很好地解決這個問題。