Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Activity生命周期的學習以及Logcat的使用

Activity生命周期的學習以及Logcat的使用

編輯:Android開發實例

   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方法所通知:
  1. public class Activity extends ApplicationContext { 
  2.      protected void onCreate(Bundle savedInstanceState); 
  3.  
  4.      protected void onStart(); 
  5.  
  6.      protected void onRestart(); 
  7.  
  8.      protected void onResume(); 
  9.  
  10.      protected void onPause(); 
  11.  
  12.      protected void onStop(); 
  13.  
  14.      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,就會看到
  1. 05-08 09:39:48.389: DEBUG/Activity1(313): onCreate   Activity 1 
  2. 05-08 09:39:48.399: DEBUG/Activity1(313): onStart    Activity 1 
  3. 05-08 09:39:48.399: DEBUG/Activity1(313): onResume   Activity 1 
   這說明一般Activity的啟動順序是onCreate -> onStart -> onResume     2. 點擊back返回鍵後
  1. 05-08 09:40:04.129: DEBUG/Activity1(313): onPause    Activity 1 
  2. 05-08 09:40:04.628: DEBUG/Activity1(313): onStop     Activity 1 
  3. 05-08 09:40:04.659: DEBUG/Activity1(313): onDestory  Activity 1 
   退出當前Activity時,onPause -> onStop -> onDestory     3. 再次啟動Activity
  1. 05-08 09:40:18.249: DEBUG/Activity1(313): onCreate   Activity 1 
  2. 05-08 09:40:18.249: DEBUG/Activity1(313): onStart    Activity 1 
  3. 05-08 09:40:18.259: DEBUG/Activity1(313): onResume   Activity 1 
  和一般啟動的順序是一樣的     4. 從Activity1啟動Acitivity2
  1. 05-08 09:40:25.477: DEBUG/Activity1(313): onPause    Activity 1 
  2. 05-08 09:40:25.687: DEBUG/Activity2(313): onCreate   Activity 2 
  3. 05-08 09:40:25.687: DEBUG/Activity2(313): onStart    Activity 2 
  4. 05-08 09:40:25.719: DEBUG/Activity2(313): onResume   Activity 2 
  5. 05-08 09:40:26.277: DEBUG/Activity1(313): onStop     Activity 1 
   Activity1.onPause -> Activity2.onCreate -> Activity2.onStart -> Activity2.onResume ->Activity1.onStop     5. 點擊Home鍵回到桌面
  1. 05-08 09:40:31.777: DEBUG/Activity2(313): onPause    Activity 2 
  2. 05-08 09:40:32.658: DEBUG/Activity2(313): onStop     Activity 2 
  Activity2.onPause - > Activity2.onStop     6. 回到原來的程序
  1. 05-08 09:40:50.429: INFO/ActivityManager(58): Starting activity: Intent ... 
  2. 05-08 09:40:50.649: DEBUG/Activity2(313): onRestart  Activity 2 
  3. 05-08 09:40:50.649: DEBUG/Activity2(313): onStart    Activity 2 
  4. 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
  1. 05-08 09:41:04.928: DEBUG/Activity2(313): onPause    Activity 2 
  2. 05-08 09:41:04.988: DEBUG/Activity1(313): onRestart  Activity 1 
  3. 05-08 09:41:04.998: DEBUG/Activity1(313): onStart    Activity 1 
  4. 05-08 09:41:04.998: DEBUG/Activity1(313): onResume   Activity 1 
  5. 05-08 09:41:05.419: DEBUG/Activity2(313): onStop     Activity 2 
  6. 05-08 09:41:05.469: DEBUG/Activity2(313): onDestory  Activity 2 
  Activity2.onPause - > Activity1.onRestart - > Activity1.onStart - > Activity1.onResume - > Activity2.onStop      8. 點擊back返回鍵後
  1. 05-08 09:41:51.868: DEBUG/Activity1(313): onPause    Activity 1 
  2. 05-08 09:41:52.428: DEBUG/Activity1(313): onStop     Activity 1 
  3. 05-08 09:41:52.468: DEBUG/Activity1(313): onDestory  Activity 1 
  Activity1 退出:onPause -> onStop -> onDestory  

保存activity狀態

   保存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的使用

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。

本文出自 “學習Android” 博客,請務必保留此出處http://android.blog.51cto.com/268543/322518

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved