1. 程式人生 > >Android之Service篇

Android之Service篇

Service知識體系圖

1.Service的基本認識

1.1 Service是什麼?

  Service(服務)是一個一種可以在後臺執行長時間執行操作而沒有使用者介面的元件。它運行於UI執行緒,因此不能進行耗時的操作。

1.2 Service和Thread的區別

  Service的執行是在UI執行緒當中的,是絕對絕對不能進行耗時操作的,而Thread開啟的子執行緒則可以進行耗時操作,但是Thread開啟的子執行緒是不能直接對UI進行操作的,否則極有可能發生直接讓程式崩掉,這就是它們的區別。

2.啟動Service的2種方式

2.1 startService()方法開啟Service

  步驟:   a.定義一個類繼承Service。   b.在AndroidManifest.xml檔案中配置該Service。   c.使用Context的startService(Intent)方法啟動該Service。   d.不再使用該Service時,呼叫Context的stopService(Intent)方法停止該Service。

2.2 bindService方法開啟Service(Activity與Service繫結)

  步驟:   a.建立BinderService服務端,繼承自Service並在類中建立一個實現IBinder介面的實現例項物件並提供公共方法給客戶端呼叫。   b.從onBind()回撥方法返回此Binder例項。   c.在客戶端中,從onServiceConnected回撥方法接收Binder,並使用提供的方法呼叫繫結服務。

3.Service的生命週期

  服務的生命週期有兩種,因為服務可以跟Activity繫結起來,也可以不繫結,Activity和服務進行通訊的話,是需要把服務和Activity進行繫結的。因此服務的生命週期分為未繫結Activity的和繫結Activity的。

沒有繫結Activity的服務生命週期圖:

未繫結Activity的服務的生命週期

繫結Activity的服務生命週期圖:

繫結Activity的服務的生命週期

1.通過Intent和startService()方法啟動了一個服務,接下來執行onCreate()方法,首次建立服務時,系統將呼叫此方法來執行一次性設定程式(在呼叫 onStartCommand() 或 onBind() 之前)。如果服務已在執行,則不會呼叫此方法。

2.當另一個元件(如 Activity)通過呼叫 startService() 請求啟動服務時,系統將呼叫此方法。一旦執行此方法,服務即會啟動並可在後臺無限期執行。 如果您實現此方法,則在服務工作完成後,需要由您通過呼叫 stopSelf() 或 stopService() 來停止服務。(如果您只想提供繫結,則無需實現此方法。)

3.服務開始處於執行狀態。

4.某個操作導致服務停止,比如執行了方法stopService(),那麼服務接下來會執行onDestory()銷燬。服務應該實現此方法來清理所有資源,如執行緒、註冊的偵聽器、接收器等。 這是服務接收的最後一個呼叫。

5.服務被完全銷燬,下一步就是等待被垃圾回收器回收了。

6.通過Intent和bindService()方法啟動了一個服務,接下來會執行onCreate()方法,首次建立服務時,系統將呼叫此方法來執行一次性設定程式(在呼叫 onStartCommand() 或 onBind() 之前)。如果服務已在執行,則不會呼叫此方法。

7.當另一個元件想通過呼叫 bindService() 與服務繫結(例如執行 RPC)時,系統將呼叫此方法。在此方法的實現中,您必須通過返回 IBinder 提供一個介面,供客戶端用來與服務進行通訊。請務必實現此方法,但如果您並不希望允許繫結,則應返回 null。

8.服務開始處於執行狀態。成功與Activity繫結。

9.某個操作導致服務解除繫結,比如執行了方法unbindService(),那麼服務接下來會解除與當前Activity的繫結。接下來服務將面臨銷燬。

10.服務執行onDestory()方法被銷燬。服務應該實現此方法來清理所有資源,如執行緒、註冊的偵聽器、接收器等。 這是服務接收的最後一個呼叫。

11.服務被完全銷燬,下一步就是等待被垃圾回收器回收了。

關於服務,總結一下:

a. 被啟動的服務的生命週期:如果一個Service被某個Activity 呼叫 Context.startService 方法啟動,那麼不管是否有Activity使用bindService繫結或unbindService解除繫結到該Service,該Service都在後臺執行。如果一個Service被startService 方法多次啟動,那麼onCreate方法只會呼叫一次,onStart將會被呼叫多次(對應呼叫startService的次數),並且系統只會建立Service的一個例項(因此你應該知道只需要一次stopService呼叫)。該Service將會一直在後臺執行,而不管對應程式的Activity是否在執行,直到被呼叫stopService,或自身的stopSelf方法。當然如果系統資源不足,android系統也可能結束服務。

b. 被繫結的服務的生命週期:如果一個Service被某個Activity 呼叫 Context.bindService 方法繫結啟動,不管呼叫 bindService 呼叫幾次,onCreate方法都只會呼叫一次,同時onStart方法始終不會被呼叫。當連線建立之後,Service將會一直執行,除非呼叫Context.unbindService 斷開連線或者之前呼叫bindService 的 Context 不存在了(如Activity被finish的時候),系統將會自動停止Service,對應onDestroy將被呼叫。

c. 被啟動又被繫結的服務的生命週期:如果一個Service又被啟動又被繫結,則該Service將會一直在後臺執行。並且不管如何呼叫,onCreate始終只會呼叫一次,對應startService呼叫多少次,Service的onStart便會呼叫多少次。呼叫unbindService將不會停止Service,而必須呼叫 stopService 或 Service的 stopSelf 來停止服務。

d. 當服務被停止時清除服務:當一個Service被終止(1、呼叫stopService;2、呼叫stopSelf;3、不再有繫結的連線(沒有被啟動))時,onDestroy方法將會被呼叫,在這裡你應當做一些清除工作,如停止在Service中建立並執行的執行緒。

特別注意:

1、你應當知道在呼叫 bindService 繫結到Service的時候,你就應當保證在某處呼叫 unbindService 解除繫結(儘管 Activity 被 finish 的時候繫結會自動解除,並且Service會自動停止);

2、你應當注意 使用 startService 啟動服務之後,一定要使用 stopService停止服務,不管你是否使用bindService;

3、同時使用 startService 與 bindService 要注意到,Service 的終止,需要unbindService與stopService同時呼叫,才能終止 Service,不管 startService 與 bindService 的呼叫順序,如果先呼叫 unbindService 此時服務不會自動終止,再呼叫 stopService 之後服務才會停止,如果先呼叫 stopService 此時服務也不會終止,而再呼叫 unbindService 或者 之前呼叫 bindService 的 Context 不存在了(如Activity 被 finish 的時候)之後服務才會自動停止;

4、當在旋轉手機螢幕的時候,當手機螢幕在“橫”“豎”變換時,此時如果你的 Activity 如果會自動旋轉的話,旋轉其實是 Activity 的重新建立,因此旋轉之前的使用 bindService 建立的連線便會斷開(Context 不存在了),對應服務的生命週期與上述相同。

5、在 sdk 2.0 及其以後的版本中,對應的 onStart 已經被否決變為了 onStartCommand,不過之前的 onStart 任然有效。這意味著,如果你開發的應用程式用的 sdk 為 2.0 及其以後的版本,那麼你應當使用 onStartCommand 而不是 onStart。

4.Service的使用場景