一個Service有兩種形态 被啟動 (Started)
onStartCommand()
當調用stopService()或者stopSelf()時結束目前Service 被綁定(Bound) onBind()當所有元件都調用unbindService()時結束目前Service
Service運作在宿主程序的主線程中,不會自動生成自己的線程,是以在Service中有耗時操作時,需要建立自己的線程避免ANR錯誤。
Service需要實作的幾個重要回調方法:
- onStartCommand() 調用
startService()時将先回調此方法,當此方法被執行時,意味着在背景啟動了一個無限期的服務,開發者需要維護Service自身的生命周期,當任務完成時,可以在Service内部調用stopSelft()或者在Service外部調用 stopService()結束服務。如果你僅使用 bindService()方法啟動Service時,可以不實作此方法。
-
bindService()時回調此方法,此方法會傳回用于clients端和Service進行通信的IBinder對象。你必須實作此方法,如果你不想bind服務的話,隻需要傳回null就行了。onBind() 當Android元件調用
- onCreate()當Service初次被建立的時候回調此方法,友善用于實作初始化操作。
- onDestroy() 當Service即将被銷毀時回調此方法,友善用于開發者釋放資源。
在AndroidManifest.xml中配置Service的注意事項:
- 可以設定
android:exported為false,以避免外部應用通路
-
android:permission以添權重限,以避免外部應用通路可以單獨設定Service的
- 如果你的Service作為public API使用時, android:name不能輕易修改 (http://android-developers.blogspot.hk/2011/06/things-that-cannot-change.html)
- 僅應用内單獨使用的Service最好不要設定intent-filter,推薦使用explicit intent(顯示意圖)
兩種Service的父類
- Service
- IntentService 當不需要Service内部同時處理多個請求時,推薦繼承此類。這個類内部定義了 worker thread,是以不像Service類那樣需要開發者再建立新的thread以避免ANR。繼承此類隻需要實作
onHandleIntent(),
需要注意的是當有多個start請求同時到來時,會按先後次序排列任務,當其中的某個任務耗時過長将會阻塞後邊的任務。
onStartCommand()
傳回值
- START_NOT_STICKY 被殺後不會自動重新開機,最安全的使用方式
- START_STICKY 被殺後會重新開機并帶有 null Intent,适用于MediaPlayer
- START_REDELIVER_INTENT 被殺後會重新開機,并帶有被殺前的最後一個Intent,适用于下載下傳檔案
内部停止服務的注意事項:當處理并發啟動服務時,onStartCommand()會被同時調用多次,有可能在調用 stopSelf()時,正好有onStartCommand()的調用,可能會丢失處理任務,是以API中提供了另一種stopSelf(int startId)的方法,在onStartcommand()中有一個startId參數,當stopSelf中的startId與啟動時的startId不符時,就不會停止服務。
閱讀原文