android 四大組件之--------------Service

Service《二》

 

 

1Service的種類

  

按運行地點分類:


 
 其實remote服務還是很少見的,並且一般都是系統服務。

按運行類型分類:


 
有同學可能會問,後臺服務我們可以自己創建 ONGOING 的 Notification 這樣就成爲前臺服務嗎?答案是否定的,前臺服務是在做了上述工作之後需要調用 startForeground ( android 2.0 及其以後版本 )或 setForeground android 2.0 以前的版本)使服務成爲 前臺服務。這樣做的好處在於,當服務被外部強制終止掉的時候,ONGOING 的 Notification 任然會移除掉。

按使用方式分類:


 
以上面三種方式啓動的服務其生命週期也有區別,將在隨後給出。

2Service 與 Thread 的區別

  

很多時候,你可能會問,爲什麼要用 Service,而不用 Thread 呢,因爲用 Thread 是很方便的,比起 Service 也方便多了,下面我詳細的來解釋一下。

 

1). ThreadThread 是程序執行的最小單元,它是分配CPU的基本單位。可以用 Thread 來執行一些異步的操作。

2). ServiceService android的一種機制,當它運行的時候如果是Local Service,那麼對應的 Service 是運行在主進程的 main 線程上的。如:onCreateonStart 這些函數在被系統調用的時候都是在主進程的 main 線程上運行的。如果是Remote Service,那麼對應的 Service 則是運行在獨立進程的 main 線程上。因此請不要把 Service 理解成線程,它跟線程半毛錢的關係都沒有!

  

既然這樣,那麼我們爲什麼要用 Service 呢?其實這跟 android 的系統機制有關,我們先拿 Thread 來說。Thread 的運行是獨立於 Activity 的,也就是說當一個 Activity 被 finish 之後,如果你沒有主動停止 Thread 或者 Thread 裏的 run 方法沒有執行完畢的話,Thread 也會一直執行。因此這裏會出現一個問題:當 Activity 被 finish 之後,你不再持有該 Thread 的引用。另一方面,你沒有辦法在不同的 Activity 中對同一 Thread 進行控制。

  

舉個例子:如果你的 Thread 需要不停地隔一段時間就要連接服務器做某種同步的話,該 Thread 需要在 Activity 沒有start的時候也在運行。這個時候當你 start 一個 Activity 就沒有辦法在該 Activity 裏面控制之前創建的 Thread。因此你便需要創建並啓動一個 Service ,在 Service 裏面創建、運行並控制該 Thread,這樣便解決了該問題(因爲任何 Activity 都可以控制同一 Service,而系統也只會創建一個對應 Service 的實例)。

  

因此你可以把 Service 想象成一種消息服務,而你可以在任何有 Context 的地方調用 Context.startServiceContext.stopServiceContext.bindServiceContext.unbindService,來控制它,你也可以在 Service 裏註冊 BroadcastReceiver,在其他地方通過發送 broadcast 來控制它,當然這些都是 Thread 做不到的。

  

3Service的生命週期

 

onCreateonStartonDestroyonBind 

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

 

2). 被綁定的服務的生命週期:如果一個Service被某個Activity 調用 Context.bindService 方法綁定啓動,不管調用 bindService 調用幾次,onCreate方法都只會調用一次,同時onStart方法始終不會被調用。當連接建立之後,Service將會一直運行,除非調用Context.unbindService 斷開連接或者之前調用bindService 的 Context 不存在了(如Activityfinish的時候),系統將會自動停止Service,對應onDestroy將被調用。

 

3). 被啓動又被綁定的服務的生命週期:如果一個Service又被啓動又被綁定,則該Service將會一直在後臺運行。並且不管如何調用,onCreate始終只會調用一次,對應startService調用多少次,ServiceonStart便會調用多少次。調用unbindService將不會停止Service,而必須調用 stopService 或 Service的 stopSelf 來停止服務。

 

4). 當服務被停止時清除服務:當一個Service被終止(1、調用stopService2、調用stopSelf3、不再有綁定的連接(沒有被啓動))時,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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章