Android服务部分总结
Service是一個可以在后臺執行長時間運行操作而不需要提供用戶操作界面的應用組件,服務可由其他應用組件啟動,而且即使用戶切換到其他應用,服務仍將在后臺繼續運行,組件可以綁定到服務,與之進行交互,甚至執行進程間的通信。
服務基本上分為兩種形式:
啟動------Activity通過調用startService()啟動服務時,服務即處于“啟動”狀態,一旦啟動,服務可以在后臺無限期運行,即使啟動服務的組件被銷毀也不受影響,已啟動的服務通常是執行單一操作,且不會將結果返回調用方,例如下載或者上傳,當操作完成時,服務自行停止。
綁定------Activity通過調用bindService()綁定服務時,服務即處于“綁定”狀態,綁定服務提供了一個客戶端服務器接口,允許組件與服務進行交互,發送請求,獲取結果,利用進場間通信跨進程執行操作。僅當與另一個應用組件綁定時,綁定的服務才會運行,多個組件可以同時綁定到該服務,但全部取消后,服務即被銷毀。
注意,兩種方式可以同時運行,即可以啟動服務,又可以綁定,問題在于是否實現了一組回調方法onStartCommand()和onBind()。
無論應用是處于啟動還是綁定,或者綁定且啟動狀態,都可以像使用Activity那樣通過調用Intent使用服務,不過,可以通過清單文件將服務聲明為私有,并阻止其他應用訪問。
注意,服務在其托管進程的主線程中運行,既不創建自己的線程,也不在單獨的進程中運行,這意味著,如果服務將執行任何CPU密集型工作或者阻止性操作,應在服務內創建新線程來完成該工作,通過使用單獨的線程,可以降低“應用無響應”(ANR)錯誤的風險,而應用主線程仍可以繼續專注于用戶與Activity之間的交互。
創建服務
創建服務,必須創建Service的子類或者使用一個已有子類,需要重寫一些回調方法,以處理服務生命周期的某些關鍵方面并提供一種機制將組建綁定到服務,應重寫的回調方法有:
onStartCommand()---當另一個組件通過調用startService()請求啟動服務時,系統將調用此方法,一旦執行此方法,服務就會啟動并有可能后臺無限運行,若實現此方法,在服務工作完成后,需要通過調用stopSelf()或stopService()來停止服務。
onBind()---當另一個組件通過調用bindService()與服務綁定時,系統將調用此方法,在實現此方法中,必須通過返回IBinder提供一個借口,供客戶端與服務器通信。若不希望允許綁定,應返回null
onCreate()---首次創建服務時,將調用此方法來執行一次性設置,在調用onStartCommand()或onBind()之前。
onDestroy()---當服務不在使用且被銷毀時,系統調用此方法,服務實現此方法,清理所有資源,這是服務接受的最后一個調用。
如果組件通過調用startService()啟動服務,這會導致onStartCommand()的調用,則服務將一直運行,知道服務使用stopSlelf()自行停止運行,或由其他組件通過調用stopService()停止為止。
如果組件是通過調用bindService()來創建服務且未調用onStartCommand(), 則服務只會在該組件與其綁定時運行,一旦服務與所有客戶端之間的綁定全部取消,系統便會銷毀它。
在清單文件中聲明服務
為確保應用安全,一定始終使用顯示Intent啟動或綁定Service,且不為服務聲明Intent過濾器。可以添加android:exported屬性,設置為”false“,確保服務僅適用于此應,可以有效阻止其他應用啟動這項服務。
創建啟動服務
Service---適用于所有服務的基類,擴展此類時,必須創建一個用于執行所有服務工作的新線程,因為默認時,服務將使用應用的主線程,這回降低應用正在運行的所有Activity的性能。
IntentService---這是Service的子類,使用工作線程逐一處理所有啟動請求。只需要實現onHandIntent()方法即可,該方法會接受每個啟動請求的Intent。
擴展IntentService類
大多數啟動服務都不必同時處理多個請求,因此,使用IntentService類實現服務也許是最好的選擇。
IntentService執行以下操作:
*創建默認的工作線程,用于在應用的主線程外執行傳遞給onStartCommand()的所有Intent。
*創建工作隊列,用于將Intent逐一傳遞給onHandIntent()實現,這樣不必擔心多線程的問題。
*在處理完所有啟動請求后停止服務,故不必調用stopSelf()。
*提供onBind()的默認實現(返回null)。
*提供onStartCommand()的默認實現,可將Intent依次發送到工作隊列和onHandleIntent()實現。
綜上所述,只需事先onHandleIntent()來完成客戶端提供的工作即可。
以下是IntentService的實現實例:
public class HelloIntentService extends IntentService {public HelloIntentService() {super("HelloIntentService");}@Overrideprotected void onHandleIntent(Intent intent) {try {Thread.sleep(5000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}} }只需一個構造函數和一個onHandleIntent()實現即可。如果還要重寫其他回調方法(如onCreate(), onStartCommand(), onDestroy())確保調用超類實現,以便IntentService能夠妥善處理工作線程的生命周期。
擴展服務類
使用IntentService顯著簡化了啟動服務的實現,但是若要求服務執行多線程,而不是通過工作對聯處理啟動請求,則可擴展Service類來處理每個Intent。
以下是提供了Service類實現的代碼,執行的工作與上述IntentService相同,級每個啟動請求,均使用工作線程執行作業,且每次僅處理一個請求。
START_NOT_STICKY----最安全的選項
START_STICKY---適用于不執行命令但無限期運行并等待作業的媒體播放器
START_REDELIVER_INTENT---適用于主動執行應該立即恢復的作業(如:下載)
啟動服務:
可以通過將Intent傳遞給startService(),從Activity或其他應用組件啟動服務,Android系統調用onStartCommand()方法,并向其傳遞Intent。注意,切勿直接調用onStartCommand()。
如,Activity可以結合使用顯示Intent與startService()啟動服務:
Intent intent = new Intent(this, HelloService.class); startService(intent);startService()方法立即返回,且Android系統調用服務的onStartCommand()方法,如果服務尚未運行,則系統先調用onCreate(),然后調用onStartCommand()。多個服務啟動請求,會導致多次對服務的onStartCommand()調用,但停止只需一次服務停止調用(stopSelf()或stopService()).停止服務
啟動服務必須管理自己的生命周期,即除非系統必須回收內存資源,否則系統不會停止或銷毀服務,故服務必須通過調用stopSelf()來自行停止運行,或者另一個組件通過調用stopService()來停止。
調用stopSelf(int)傳遞與停止請求對應的ID服務,指定停止對應ID的服務,若stopService()會停止全部服務。
創建綁定服務
綁定服務允許應用組件通過調用bindService()與其綁定,以便創建長期連接,通常不允許組件通過調用startService()來啟動。
要創建綁定服務,必須實現onBind()回調方法以但會IBinder,用于定義與服務通信的接口。然后其他Activity可以調用bindService()來檢索該接口,并開始對服務調用方法,若沒有組件綁定到服務,系統會自動銷毀該服務。服務于客戶端之間的接口必須是IBinder的實現,且服務必須從onBind()回調方法返回,一旦客戶端收到IBinder,即開始通過該接口與服務進行交互。多個客戶端可以同時綁定到服務,客戶端完成與服務的交互后,會調用unbindService()取消綁定,一旦沒有客戶端與服務綁定,則系統會銷毀掉服務。
向用戶發送通知
服務可以使用Toast通知或狀態欄通知來通知用戶所發生的事件。通常,狀態欄通知是最好的。
在前臺運行服務
前臺服務即使在內存不足時,系統也不會終止,必須在狀態欄提供通知,除非服務停止或被移除,否則不能清除通知。
讓服務運行在前臺,需調用startForeground()采用兩個參數,唯一標識通知的整型數和狀態欄的Notification,例如:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),System.currentTimeMillis()); Intent notificationIntent = new Intent(this, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, getText(R.string.notification_title),getText(R.string.notification_message), pendingIntent); startForeground(ONGOING_NOTIFICATION_ID, notification);注意,startForeground()的整型ID不得為0若要從前臺移除,調用stopForeground()采用一個布爾值,指示是否也移除狀態欄通知,此方法不會停止服務,但如果在服務正在前臺運行時將其停止,則通知也會被移除。
管理服務生命周期:
服務的生命周期比Activity生命周期簡單,但更應密切關注如何創建和銷毀服務。
服務生命周期有兩條路徑:
啟動服務:在Activity調用startService()時創建,然后無限運行,必須通過調用stopSelf()來自行停止運行。其他組件也可以調用stopService()來停止服務。服務停止后,系統將其銷毀。
綁定服務:服務在客戶端調用bindService()時創建,然后客戶端通過IBinder接口與服務進行通信。客戶端可以通過調用unbindService()關閉連接,多個客戶端可以綁定到相同的服務,但所有綁定都取消后,系統自動銷毀服務。
這兩條路徑并非完全獨立,可以綁定到已經使用startService()啟動的服務,例如,可以通過使用Intent調用startService()來啟動后臺服務,之后Activity可以通過調用bindService()綁定到服務,除非所有客戶端都取消綁定,否則stopService()或stopSelf()不會停止服務。
服務生命周期的回調:
與Activity類似,可以實現服務生命周期的回調方法來監控服務狀態或添加執行工作。
public class ExampleService extends Service {int mStartMode; //表明如果服務銷毀時行為IBinder mBinder; //綁定客戶端的接口boolean mAllowRebind; //表明重新綁定是否應該被綁定@Overridepublic void onCreate() {//服務被創建}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//開始服務,因為調用了startService()方法return mStartMode;}@Overridepublic IBinder onBind(Intent intent) {//一個客戶端正在調用bindService()綁定到服務return mBinder;}@Overridepublic boolean onUnbind(Intent intent) {//全部客戶端通過調用unbindService()取消綁定 return mAllowRebind;}@Overridepublic void onRebind(Intent intent) {//一個客戶端正在調用bindService()綁定到服務//在onUnbind()被調用后}@Overridepublic void onDestroy() {//服務不在被使用且被銷毀后} }服務的有效生命周期從調用onStartCommand()或onBind()開始,每種方法均由Intent對象,分為傳遞到startService()或bindService(),啟動服務的有效生命周期與整個生命周期同時結束,綁定服務的有效生命周期在onUnbind()返回時結束。
總結
以上是生活随笔為你收集整理的Android服务部分总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Activity本质和内部实现机制
- 下一篇: Service中的绑定服务总结