Service的生命週期與Activity生命週期區別

 碰到一面試題    簡述activity/service生命週期android

組件的生命週期 面試

應用程序組件都有一個生命週期,從響應Intent的Android實例開始到這個實例被銷燬。在這期間,他們或許有效或許無效,有效時或許對用戶可見或許不可見。下面咱們就來討論四個基本組件的生命週期,包括在生命週期內的各類狀態,以及狀態之間的轉換。這幾種狀態可能的結果是:進程讓他們中止, 而後實例被銷燬。 
1、activity生命週期 
   一個activity有三個基本的狀態: 
@ 當activity在前臺運行時(在activity當前任務的堆棧頂),爲活動或者運行狀態。這時activity會響應用戶的操做。 
@ 當activity失去焦點可是對用戶仍然可見時爲paused暫停狀態。此時,別的activity在他的上面,透明或者備有被所有覆蓋。因此其中一些暫停的activity也能夠被顯示。一個暫停的activity是處於活動狀態的(他維護着全部的狀態保存着信息,而且依然附着在窗口管理器)。 
@ 若是一個activity徹底被另外一個activity所掩蓋那他會處於stop狀態。但仍然保存着原來的狀態和信息。然而,若是別的地方須要更多的內存並且這個activity仍一直處於隱藏狀態,那麼系統有可能會殺死他的進程。 
若是一個activity是暫停或者中止狀態,系統能夠清理他們佔用的內存,或者調用finish()方法,或者直接結束他的進程。當他再次顯示給用戶時,會徹底的從新運行而且加載之前所存儲的信息。 
activity狀態之間的轉換,是經過之前的受保護方法完成的: 
void onCreate(Bundle savedInstanceState) 
void onStart() 
void onRestart() 
void onResume() 
void onPause() 
void onStop() 
void onDestroy() 

這些都是鉤子函數,你能夠重寫他們,當狀態改變時作一些適當的處理。全部的activity在首次運行時必須實現onCreate()方法來初始化安裝。activity能夠實現onPause()來提交數據改變,而後準備中止與用戶的交互。 
調用超類 

每個實現的activity生命週期方法都會先調用一下父類的方法,例如: 
view plaincopy to clipboardprint? 
protected void onPause() {   
    super.onPause();   
    . . .   

protected void onPause() { 
    super.onPause(); 
    . . . 


經過這二者比較?,這7個方法定義了一個activity的整個生命週期的方法。你能夠實現而且監測這三個嵌套循環: 

@ 整個生命週期 
調用onCreate()方法和onDestroy()之間稱爲一個activity的完整的生命週期。activity會在onCreate()裏執行全部的初始化安裝,在onDestroy()方法裏釋放全部的剩餘資源。例如:一個從網絡下載程序的線程,就須要在onCreate()方法裏建立,在onDestroy()方法裏銷燬。 

@ 可見生命週期 
可見生命週期是從onStart()方法到onStop()方法的時間。這段時間,用戶會在屏幕上看到這個activity。儘管他可能不是在最頂層顯示,也沒有和用戶進行任何交互。這兩個方法之間,你能夠保持須要向用戶顯示的資源。例如:你能夠在onStart()方法時註冊一個BroadcastReceiver檢測某些變化來改變你的界面,當用戶看不到這個activity的界面時能夠在onStop()裏註銷這個BroadcastReceiver。這兩個方法能夠被調用不少次,在可見和對用戶隱藏時,做爲候補的activity待命。 

@ 前臺顯示週期 
一個activity從onResume()方法指導一個onPause()方法稱爲前臺顯示週期。此時他在其餘的activity之上顯示而且與用戶交互。一個activity能夠頻繁的在這兩個方法之間過分,例如:當設備休眠或者另外一個新的activity啓動時,它會進入onPause()狀態,當一個activity運行結束或者新的接收到Intent請求時,activity的onResume()會被調用。所以,這兩個方法裏的代碼量會不多。 

下圖說明了上面說的幾個循環,裏面的箭頭說明了兩個狀態之間是否能夠相互轉換。有色的橢圓是activity主要的幾個狀態。正方形和長方形表明activity在狀態之間轉變時咱們能夠實現的一些回調方法。 

注意killable這列,它指明瞭進程在調用方法返回後是否能夠被系統殺死,而不執行其餘的代碼。onPause(), onStop(), and onDestroy()這三個方法能夠,由於onPause方法首先被執行,他是惟一一個必定會被調用的方法當進程被殺死時,可是onStop()和onDestroy()方法不會。所以,你能夠在onPause()方法裏保存一些連續的數據,例如編輯。 
killable這列被標記成no的方法,保護activity防止他們被調用時,被進程殺死。例如:一個activity是處於可被殺死的狀態,當activity從onPause()方法跳轉到onResume()方法時,在OnPause方法回調以前是不會被殺死的。 

正如後面的章節:進程和生命週期,一個沒有定義爲「killable」的activity仍然能夠被系統結束,但這時會發生在特殊狀況下,好比沒有其餘資源時。 

保存activity的狀態 

當系統(而不是用戶)關閉一個activity來節省內存時,用戶但願再次啓動activity時會回到當時的狀態。 
爲了在activity被殺死以前捕獲他的狀態,你能夠實現 onSaveInstanceState()方法,Android會在一個activity將要被關閉時調用這個方法,也就是在onPause()方法以前。他回傳遞給方法一個Bandle對象,你能夠用key-value的方式保存你的數據。當activity再次運行時。這個Bandle對象會傳遞給onCreate()方法、onStart()方法、onRestoreInstanceState()方法。這幾個方法都能重建當時的activity狀態。 

不像onPause()和剛纔討論的其餘幾個方法,onSaveInstanceState()和onRestoreInstanceState()方法不是生命週期方法。不是否是總被調用。例如:Android在activity將要被系統銷燬以前調用onSaveInstanceState()方法,當activity實例被用戶的操做銷燬時(例如按下Back鍵),是不會調用這個方法的。這種狀況下沒有理由保存他的狀態。 

Coordinating activities 
當一個activity啓動了另外一個activity,他們都經歷了生命週期的轉換。一個暫停了或者結束了,其餘的activity啓動。一種狀況你可能須要調節這些activity: 
生命週期方法的回調順序都是定義好的,尤爲當兩個activity在同一進程下: 

1.當前運行的activity的onPause()方法被調用。 
2.而後將要運行的activity的onCreate()、onStart()、onResume()方法被依次調用。 
3.而後,若是將要運行的activity不太可見,那麼onstop()方法會被調用。 
2、Service的生命週期: 
有了 Service 類咱們如何啓動他呢,有兩種方法: 

      • Context.startService() 
      • Context.bindService() 
     1.  在同一個應用任何地方調用 startService() 方法就能啓動 Service 了,而後系統會回調 Service 類的 onCreate() 以及 onStart() 方法。這樣啓動的 Service 會一直運行在後臺,直到 Context.stopService() 或者 selfStop() 方法被調用。另外若是一個 Service 已經被啓動,其餘代碼再試圖調用 startService() 方法,是不會執行 onCreate() 的,但會從新執行一次 onStart() 。 
      2. 另一種 bindService() 方法的意思是,把這個 Service 和調用 Service 的客戶類綁起來,若是調用這個客戶類被銷燬,Service 也會被銷燬。用這個方法的一個好處是,bindService() 方法執行後 Service 會回調上邊提到的 onBind() 方發,你能夠從這裏返回一個實現了 IBind 接口的類,在客戶端操做這個類就能和這個服務通訊了,好比獲得 Service 運行的狀態或其餘操做。若是 Service 尚未運行,使用這個方法啓動 Service 就會 onCreate() 方法而不會調用 onStart()。 
      總結: 
      1. startService()的目的是回調onStart()方法,onCreate() 方法是在Service不存在的時候調用的,若是Service存在(例如以前調用了bindService,那麼Service的onCreate方法已經調用了)那麼startService()將跳過onCreate() 方法。 
      2.  bindService()目的是回調onBind()方法,它的做用是在Service和調用者之間創建一個橋樑,並不負責更多的工做(例如一個Service須要鏈接服務器的操做),通常使用bindService來綁定到一個現有的Service(即經過StartService啓動的服務)。 
      因爲Service 的onStart()方法只有在startService()啓動Service的狀況下才調用,故使用onStart()的時候要注意這點。 
與 Service 通訊而且讓它持續運行 
      若是咱們想保持和 Service 的通訊,又不想讓 Service 隨着 Activity 退出而退出呢?你能夠先 startService() 而後再 bindService() 。當你不須要綁定的時候就執行 unbindService() 方法,執行這個方法只會觸發 Service 的 onUnbind() 而不會把這個 Service 銷燬。這樣就能夠既保持和 Service 的通訊,也不會隨着 Activity 銷燬而銷燬了。 
提升 Service 優先級 
      Android 系統對於內存管理有本身的一套方法,爲了保障系統有序穩定的運信,系統內部會自動分配,控制程序的內存使用。當系統以爲當前的資源很是有限的時候,爲了保 證一些優先級高的程序能運行,就會殺掉一些他認爲不重要的程序或者服務來釋放內存。這樣就能保證真正對用戶有用的程序仍然再運行。若是你的 Service 碰上了這種狀況,多半會先被殺掉。但若是你增長 Service 的優先級就能讓他多留一會,咱們能夠用 setForeground(true) 來設置 Service 的優先級。 
      爲何是 foreground ? 默認啓動的 Service 是被標記爲 background,當前運行的 Activity 通常被標記爲 foreground,也就是說你給 Service 設置了 foreground 那麼他就和正在運行的 Activity 相似優先級獲得了必定的提升。當讓這並不能保證你得 Service 永遠不被殺掉,只是提升了他的優先級。 
3、android的service的生命週期與activity相似,可是有一些不一樣: 
onCreate和onStart是不一樣的 
經過從客戶端調用Context.startService(Intent)方法咱們能夠啓動一個服務。若是這個服務尚未運行,Android將啓動它而且在onCreate方法以後調用它的onStart方法。若是這個服務已經在運行,那麼它的onStart方法將被新的Intent再次調用。因此對於單個運行的Service它的onStart方法被反覆調用是徹底可能的而且是很正常的。 

onResume、onPause以及onStop是不須要的 

回調一個服務一般是沒有用戶界面的,因此咱們也就不須要onPause、onResume或者onStop方法了。不管什麼時候一個運行中的Service它老是在後臺運行。 
onBind 
若是一個客戶端須要持久的鏈接到一個服務,那麼他能夠調用Context.bindService方法。若是這個服務沒有運行方法將經過調用onCreate方法去建立這個服務但並不調用onStart方法來啓動它。相反,onBind方法將被客戶端的Intent調用,而且它返回一個IBind對象以便客戶端稍後能夠調用這個服務。同一服務被客戶端同時啓動和綁定是很正常的。 
onDestroy 

與Activity同樣,當一個服務被結束是onDestroy方法將會被調用。當沒有客戶端啓動或綁定到一個服務時Android將終結這個服務。與不少Activity時的狀況同樣,當內存很低的時候Android也可能會終結一個服務。若是這種狀況發生,Android也可能在內存夠用的時候嘗試啓動被終止的服務,因此你的服務必須爲重啓持久保存信息,而且最好在onStart方法內來作。 服務器


--------------------------------------------------------------------------------------------------網絡

activity的生命週期函數

oncreate(Bundle savedInstanceState):在activity第一次被建立的時候調用。這裏是你作全部初始化設置的地方──建立視圖、綁定數據至列表等。若是曾經有狀態記錄,則調用此方法時會傳入一個包含着此activity之前狀態的包對象作爲參數 動畫

onRestart():在activity中止後,在再次啓動以前被調用。 spa

onStart():當activity正要變得爲用戶所見時被調用。線程

onResume():在activity開始與用戶進行交互以前被調用。此時activity位於堆棧頂部,並接受用戶輸入。 對象

onPause():當系統將要啓動另外一個activity時調用。此方法主要用來將未保存的變化進行持久化,中止相似動畫這樣耗費CPU的動做等。這一切動做應該在短期內完成,由於下一個activity必須等到此方法返回後纔會繼續。 blog

onStop():當activity再也不爲用戶可見時調用此方法。這可能發生在它被銷燬或者另外一個activity(多是現存的或者是新的)回到運行狀態並覆蓋了它。

onDestroy():在activity銷燬前調用。這是activity接收的最後一個調用。這可能發生在activity結束(調用了它的 finish() 方法)或者由於系統須要空間因此臨時的銷燬了此acitivity的實例時。你能夠用isFinishing() 方法來區分這兩種狀況。

協調activity

當一個activity啓動了另一個的時候,它們都會經歷生命週期變化。一個會暫停乃至中止,而另外一個則啓動。這種狀況下,你可能須要協調好這些activity:

生命週期回調順序是已經定義好的,尤爲是在兩個activity在同一個進程內的狀況下:

1. 調用當前activity的 onPause() 方法。 

2. 接着,順序調用新啓動activity的onCreate()、 onStart()和onResume()方法。 

3. 而後,若是啓動的activity再也不於屏幕上可見,則調用它的onStop()方法。 


總之:一、Activity 從建立到進入運行態所觸發的事件  onCreate()-->onStart-->onResume()

          二、從運行態到中止態所觸發的事件                  onPause()--->onStop()

          三、從中止態到運行態所觸發事件                     onRestart()-->onStart()--->onResume()

     四、從運行態到暫停態所觸發事件                     onPause()

          五、從暫停態到運行態所觸發事件                     onResume()

橫豎屏幕切換生命週期

1.不設置Activity的android:configChanges時,切屏會從新調用各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次. 

2.設置Activity的android:configChanges="orientation"時,切屏仍是會從新調用各個生命週期,切橫、豎屏時只會執行一次. 

3.設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會從新調用各個生命週期,只會執行onConfigurationChanged方法.

service的生命週期

啓動Service時可調用startService和bindService()方法來啓動,用這兩種方法啓動的Service的生命週期是不一樣的。

Service的生命週期只有onCreate,onStart和onDestroy,沒有onResume,onPause和onStop,大多數時間Service都是運行的,但在嚴重的內存壓力下它也可能被系統kill,若是被kill,系統會在稍後嘗試從新啓動這個Service

Service的調用

途徑一:
調用Context.startService()啓動Service,調用Context.stopService()或Service.stopSelf()或Service.stopSelfResult()關閉Service的調用。

Service生命週期分析:
注:onCreate,onStart(),onDestroy()是Service生命週期相關的方法
當Context.startService()啓動Service時,若是Service自己沒有運行,則調用onCreate()->onStart()完成Service啓動。若是Service已經運行,則只調用onStart(),onStart()能夠屢次被調用。
Service關閉必須調用Context.stopService()或Service.stopSelf()或Service.stopSelfResult()方法,關閉以前調用onDestroy()方法,不然若是Context直接退出而沒有中止Service的話,Service會一直在後臺運行。該Service的調用者只能再啓動後經過stopService關閉Service。
生命週期順序爲:onCreate()->onStart()->onDestroy()

途徑二:
調用Context.bindService()進行初始化綁定,使用Context.unbindService()取消綁定,因爲Service和Context是綁定關係,當Context退出或被銷燬時,Service也會相應退出。

Service生命週期分析:
調用Context.bindService()時,Service會經歷onCreate->onBind(),onBind將返回給客戶端一個IBind實例,IBind容許客戶端回調服務的方法。此時Context和Service是綁定在一塊兒的,Context退出了,Service調用onUnbind()->onDestroy()相應退出。
生命週期順序爲:onCreate->onBind(只一次,不可屢次綁定)->onUnbind->onDestroy()

BroadcastReceiver只能經過startService啓動Service,由於廣播自己生命週期很短,bind的話沒有意義

果不是經過bindService建立的服務(但仍然經過bindService獲得了服務對象),就可能unbindService後還在運行,不然應該是結束掉了。
相關文章
相關標籤/搜索