Activities是由Activity stack管理的。當一個新的Activity被啓動,它就會處於stack的top位置,成爲當前運行的Activity。而前一個Activity依然保留在stack裏面,當須要調用這個Activity時就會回到stack的top位置成爲當前運行的Activity。
一個Activity有4個基本狀態:
1. active / running 狀態,當Activity處於當前屏幕時;
2. paused 狀態,當Activity失去焦點但對用戶依然可見時;便是,一個非全屏或者透明的Activity在該Activity的屏幕上面,併成爲了當前的焦點。而paused的Activity依然是alive狀態的,它保留着全部的狀態和成員信息並鏈接至窗口管理器,但當系統處於極低內存的狀況下,仍然能夠殺死這個Activity。
3. stopped 狀態,當Activity徹底被另外一個Activity覆蓋時;它仍然保留全部的狀態和成員信息。但它再也不被用戶可見,因此它的窗口將被隱藏,當其它地方須要內存,則系統常常會殺死這個Activity。
4. 當Activity是paused或者stopped狀態時,系統能夠經過要求它結束(調用它的finish()方法)或直接殺死它的進程來將它驅出內存。當它再次爲用戶可見的時候,它只能徹底從新啓動並恢復至之前的狀態。
怎麼來理解Activity的狀態及其生命週期呢?引用網友的解釋:
「因爲手機應用的一些特殊性,因此咱們須要更多的去關注各個Android Component的運行時生命週期模型。(所謂手機應用的特殊性主要是指這樣2點: 1. 手機應用的大多數狀況下咱們只能在手機上看到一個程序的一個界面 ,用戶除了經過程序界面上的功能按鈕來在不一樣的窗體間切換,還能夠經過Back鍵和Home鍵來返回上一個窗口,而用戶使用Back或者Home的時機是很是不肯定的,任什麼時候候用戶均可以使用Home或Back來強行切換當前的界面。 2. 每每手機上一些特殊的事件發生也會強制的改變當前用戶所處的操做狀態,例如不管任何狀況,在手機來電時,系統都會優先顯示電話接聽界面。)瞭解這些Component的生命週期模型一方面是讓咱們對軟件在手機中的運行狀況作到心中有數,更重要的,對於程序開發來講,生命週期中的每個關鍵事件都會有咱們能夠覆寫於各類Component對應基類型的事件處理方法,瞭解各Component的生命週期就是讓咱們在開發程序時明白咱們該怎樣去編寫各類事件的處理代碼。」
「因爲前面已經說到的手機應用的特殊性,一個Activity極可能被強制
交換到後臺(交換到後臺就是指該窗體再也不對用戶可見,但實際上又仍是存在於某個Task中的,好比一個新的Activity壓入了當前的Task從而「遮蓋」住了當前的Activity,或者用戶按了Home鍵回到桌面,又或者其餘重要事件發生致使新的Activity出如今當前Activity之上,好比來電界面),而若是此後用戶在一段時間內沒有
從新查看該窗體(Android經過長按Home鍵能夠選擇最近運行的6個程序,或者用戶直接再次點擊程序的運行圖標,若是窗體所在的Task和進程沒有被系統銷燬,則不用從新加載Process, Task和Task中的Activity, 直接從新顯示Task頂部的Activity, 這就稱之爲從新查看某個程序的窗體),該窗體連同其所在的Task和Process則可能已經被系統自動銷燬了,此時若是再次查看該窗體,則要從新執行onCreate事件初始化窗體。而這個時候咱們可能但願用戶繼續上次打開該窗體時的操做狀態進行操做,而不是一切從頭開始。例如用戶在編輯短信時忽然來電,接完電話後用戶又去作了一些其餘的事情,好比保存來電號碼到聯繫人,而沒有當即回到短信編輯界面,致使了短信編輯界面被銷燬,當用戶從新進入短信程序時他可能但願繼續上次的編輯。這種狀況咱們就能夠覆寫Activity的void onSaveInstanceState(Bundle outState)事件,經過向outState中寫入一些咱們須要在窗體銷燬前保存的狀態或信息,這樣在窗體從新執行onCreate的時候,則會經過savedInstanceState將以前保存的信息傳遞進來,此時咱們就能夠有選擇的利用這些信息來初始化窗體,而不是一切從頭開始。」
下面官方提供的這幅圖,描述了Activity生命週期的整個過程:
能夠看到,以上有3個關鍵的生命週期循環:
1.
一個activity 完整的生命週期 自第一次調用 onCreate(Bundle)開始,直至調用onDestroy()爲止。activity在onCreate()中設置全部"全局"狀態以完成初始化,而在onDestroy()中釋放全部系統資源。好比說,若是activity有一個線程在後臺運行以從網絡上下載數據,它會以 onCreate()建立那個線程,而以 onDestroy()銷燬那個線程。
2.
一個activity的 可視生命週期 自 onStart() 調用開始直到相應的 onStop()調用。在此期間,用戶能夠在屏幕上看到此activity,儘管它也許並非位於前臺或者正在與用戶作交互。在這兩個方法中,你能夠管控用來向用戶顯示這個activity的資源。好比說,你能夠在onStart() 中註冊一個BroadcastReceiver 來監控會影響到你UI的改變,而在onStop() 中來取消註冊,這時用戶是沒法看到你的程序顯示的內容的。onStart() 和 onStop() 方法能夠隨着應用程序是否爲用戶可見而被屢次調用。
3.
一個activity的 前臺生命週期 自 onResume() 調用起,至相應的 onPause()調用爲止。在此期間,activity位於前臺最上面並與用戶進行交互。activity會常常在暫停和恢復之間進行狀態轉換──好比說當設備轉入休眠狀態或有新的activity啓動時,將調用onPause() 方法。當activity得到結果或者接收到新的intent的時候會調用onResume() 方法。所以,在這兩個方法中的代碼應當是輕量級的。
當一個activity從這個狀態轉變到另外一個狀態時,它被如下列protected方法所通知:
- public class Activity extends ApplicationContext {
- protected void onCreate(Bundle savedInstanceState);
-
- protected void onStart();
-
- protected void onRestart();
-
- protected void onResume();
-
- protected void onPause();
-
- protected void onStop();
-
- protected void onDestroy();
- }
咱們能夠重載全部這些方法以在狀態改變時進行合適的工做。全部的activity都必須實現 onCreate() 用以當對象第一次實例化時進行初始化設置。不少activity會實現 onPause()以提交數據變化或準備中止與用戶的交互。
要注意的是,onPause(),onStop(),onDestory()這3個方法是能夠被系統直接kill的,當系統內存不足的時候。
而日常從一個activity轉向/回到另外一個activity時,當新activity是full screen(彈出窗口,例如AlertDialog是不算的)的時候就會call 前一個activity的onPause(),而後call onStop(),而不管onPause或者onStop,都有可能被kill,因此通常在onPause就會執行savedata操做將全部持久性數據(好比用戶的編輯結果)寫入存儲之中。
如今咱們來看看兩個activity在同一個進程內的調用狀況:
1. 調用當前activity的 onPause() 方法。
2. 接着調用新啓動activity的onCreate()、 onStart()和onResume()方法。
3. 而後,若是啓動的activity再也不於屏幕上可見,則調用它的onStop()方法。
如下我使用Logcat記錄下來的Activity調用過程當中的方法調用順序:
1. 點擊按鈕去啓動 Activity1,就會看到
- 05-08 09:39:48.389: DEBUG/Activity1(313): onCreate Activity 1
- 05-08 09:39:48.399: DEBUG/Activity1(313): onStart Activity 1
- 05-08 09:39:48.399: DEBUG/Activity1(313): onResume Activity 1
這說明通常Activity的啓動順序是
onCreate -> onStart -> onResume
2. 點擊back返回鍵後
- 05-08 09:40:04.129: DEBUG/Activity1(313): onPause Activity 1
- 05-08 09:40:04.628: DEBUG/Activity1(313): onStop Activity 1
- 05-08 09:40:04.659: DEBUG/Activity1(313): onDestory Activity 1
退出當前Activity時,onPause -> onStop -> onDestory
3. 再次啓動Activity
- 05-08 09:40:18.249: DEBUG/Activity1(313): onCreate Activity 1
- 05-08 09:40:18.249: DEBUG/Activity1(313): onStart Activity 1
- 05-08 09:40:18.259: DEBUG/Activity1(313): onResume Activity 1
和通常啓動的順序是同樣的
4. 從Activity1啓動Acitivity2
- 05-08 09:40:25.477: DEBUG/Activity1(313): onPause Activity 1
- 05-08 09:40:25.687: DEBUG/Activity2(313): onCreate Activity 2
- 05-08 09:40:25.687: DEBUG/Activity2(313): onStart Activity 2
- 05-08 09:40:25.719: DEBUG/Activity2(313): onResume Activity 2
- 05-08 09:40:26.277: DEBUG/Activity1(313): onStop Activity 1
Activity1.onPause -> Activity2.onCreate -> Activity2.onStart -> Activity2.onResume ->Activity1.onStop
5. 點擊Home鍵回到桌面
- 05-08 09:40:31.777: DEBUG/Activity2(313): onPause Activity 2
- 05-08 09:40:32.658: DEBUG/Activity2(313): onStop Activity 2
Activity2.onPause - > Activity2.onStop
6. 回到原來的程序
- 05-08 09:40:50.429: INFO/ActivityManager(58): Starting activity: Intent ...
- 05-08 09:40:50.649: DEBUG/Activity2(313): onRestart Activity 2
- 05-08 09:40:50.649: DEBUG/Activity2(313): onStart Activity 2
- 05-08 09:40:50.769: DEBUG/Activity2(313): onResume Activity 2
Activity2.onRestart -> Activity2.onStart -> Activity2.onResume
7. 點擊comfirm, setResult(RESULT_OK),Activity2.finish(),返回到Activity1
- 05-08 09:41:04.928: DEBUG/Activity2(313): onPause Activity 2
- 05-08 09:41:04.988: DEBUG/Activity1(313): onRestart Activity 1
- 05-08 09:41:04.998: DEBUG/Activity1(313): onStart Activity 1
- 05-08 09:41:04.998: DEBUG/Activity1(313): onResume Activity 1
- 05-08 09:41:05.419: DEBUG/Activity2(313): onStop Activity 2
- 05-08 09:41:05.469: DEBUG/Activity2(313): onDestory Activity 2
Activity2.onPause - > Activity1.onRestart - > Activity1.onStart - > Activity1.onResume - > Activity2.onStop
8. 點擊back返回鍵後
- 05-08 09:41:51.868: DEBUG/Activity1(313): onPause Activity 1
- 05-08 09:41:52.428: DEBUG/Activity1(313): onStop Activity 1
- 05-08 09:41:52.468: DEBUG/Activity1(313): onDestory Activity 1
Activity1 退出:
onPause -> onStop -> onDestory
保存activity狀態android
保存activity狀態,是爲了方便用戶從新打開程序時,可以回到上次離開時的狀態。這裏面涉及到的方法有:
protected void onSaveInstanceState (Bundle outState)
protected void onRestoreInstanceState (Bundle savedInstanceState)
當一個Activity被kill以前,它能夠調用onSaveInstanceState()來保存當前activity的狀態信息,它會將一個以名稱-值對方式記錄了activity動態狀態的
Bundle對象傳遞給該方法。當activity再次啓動時,這個Bundle會傳遞給onCreate()方法和隨着onStart()方法調用的onRestoreInstanceState()。這兩個方法的內容通常是把要臨時保存的數據放到Bundle裏面,或者從裏面拿出來。
要注意的是,onSaveInstanceState() 和 onRestoreInstanceState() 並非生命週期方法。它們並非總會被調用。好比說,Android會在activity易於被系統銷燬以前調用 onSaveInstanceState(),但用戶動做(好比按下了BACK鍵)形成的銷燬則不調用。在這種狀況下,用戶沒打算再次回到這個activity,因此沒有保存狀態的必要。由於onSaveInstanceState()不是總被調用,因此你應該只用它來爲activity保存一些臨時的狀態,而不能用來保存持久性數據。
而是應該用onPause()來達到這個目的:�在onPause()裏面調用自定義命名的函數saveState(),在saveState裏面保存數據到數據庫。
Logcat的使用sql
1. import android.util.Log;
2. private static final String TAG = "Activity1"; 設置TAG
3. Log.d(TAG, message); log記錄信息
其中Log.v() : VERBOSE
Log.d() : DEBUG
Log.i() : INFO
Log.w() : WARN
Log.e() : ERROR
以上log的級別依次升高,Debug信息應當只存在於開發中,INFO、 WARN、ERROR這3種log將出如今發佈版本中。
4. 在Eclipse查看Log:
在菜單Window-> Show View選擇other,在彈出的窗口中選擇Android裏面的LogCat,ok,就會看到LogCat窗口,在Filter那裏能夠輸入過濾的詞語,通常是輸入TAG的內容,這樣子能夠直接看到有關這個TAG的Log。