Service
幾個問題
1. Service的start和bind狀態有什麼區別?
- 同一個Service,先startService,然後再bindService,如何把它停止掉?
- 你有注意到Service的onStartCommand方法的返回值嗎?不同返回值有什麼區別?
- Service的生命週期方法onCreate、onStart、onBind等運行在哪個線程?
學習的過程中還會遇到其它問題會一塊解決
概述
Service是一個一種可以在後臺執行長時間運行操作而沒有用戶界面的應用組件。Service可由其他應用組件啓動(如Activity,也可以是另外一個Service),Service一旦被啓動將在後臺一直運行,即使啓動服務的組件(Activity)已銷燬也不受影響。 此外,組件可以綁定到服務,以與之進行交互,甚至是執行進程間通信 (IPC)(什麼是進程間通信)。 例如,Service可以處理網絡事務、播放音樂,執行文件 I/O 或與內容提供程序交互,而所有這一切均可在後臺進行
聲明
任何 service都是通過繼承 Service 基類自定義而來,需要在AndroidManifest.xml中聲明
<service android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:isolatedProcess=["true" | "false"]
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string" >
. . .
</service>
定義
定義過程主要實現下面幾個方法
onBind()
當另一個組件想通過調用 bindService() 與服務綁定(例如執行 RPC)時,系統將調用此方法。在此方法的實現中,必須返回 一個IBinder 接口的實現類,供客戶端用來與服務進行通信。無論是啓動狀態還是綁定狀態,此方法必須重寫,但在啓動狀態的情況下直接返回 null。
onCreate()
首次創建服務時,系統將調用此方法來執行一次性設置程序(在調用 onStartCommand() 或onBind() 之前)。如果服務已在運行,則不會調用此方法,該方法只調用一次
onStartCommand()
當另一個組件(如 Activity)通過調用 startService() 請求啓動服務時,系統將調用此方法。一旦執行此方法,服務即會啓動並可在後臺無限期運行。 如果自己實現此方法,則需要在服務工作完成後,通過調用 stopSelf() 或 stopService() 來停止服務。(在綁定狀態下,無需實現此方法。)
onDestroy()
當服務不再使用且將被銷燬時,系統將調用此方法。服務應該實現此方法來清理所有資源,如線程、註冊的偵聽器、接收器等,這是服務接收的最後一個調用。
啓動
當組件通過調用 startService() 啓動服務時,服務即處於“啓動”狀態。一旦啓動,服務即可在後臺無限期運行(如何停止服務),即使啓動服務的組件已被銷燬也不受影響,除非手動調用才能停止服務, 已啓動的服務通常是執行單一操作,而且不會將結果返回給調用方。
綁定
bindService
Service處於綁定狀態時,其代表着客戶端-服務器接口中的服務器。當其他組件綁定到服務時可以從組件中去調用Service中的方法
答案
- Service的start和bind狀態有什麼區別?
startService() :
場景:一般主要用於長期後臺運行播放音樂
生命週期: onCreate(第一次會觸發)–onStartCommand(每次都會觸發)–onDestry
停止方式 外部調用 Context.stopService(service)(可以執行多次)或者自身 StopSelf()
bindService(service,conn.flags):
生命週期 onCreate–onBind(只能觸發一次)–onUnbind– onDestroy
bind啓動之後服務與組件相關聯,如果組件銷燬服務也會銷燬
停止方式 Context.unbindService(conn)(只能解綁一次,多次會拋出異常)或啓動它的 activity 銷燬
- 同一個Service,先startService,然後再bindService,如何把它停止掉?
需要分別調用stopService(當然也可以是stopSelf)和unbindService才能停止掉。前者是讓服務的啓動狀態失效,後者是讓服務的綁定狀態清除,調用順序沒有要求。當一個服務既不處於啓動狀態也沒有Context與其綁定時,即可停止掉
- 你有注意到Service的onStartCommand方法的返回值嗎?不同返回值有什麼區別
onStartCommand()方法必須返回一個整數,這個整數是一個描述了在系統的殺死事件中,系統應該如何繼續這個服務的值(雖然你能夠修改這個值,但是IntentService處理還是爲你提供了默認實現)
START_NOT_STICKY:若執行完onStartCommand()方法後,系統就kill了service,不要再重新創建service,除非系統回傳了一個pending intent。這避免了在不必要的時候運行service,您的應用也可以restart任何未完成的操作。
START_STICKY:若系統在onStartCommand()執行並返回後kill了service,那麼service會被recreate並回調onStartCommand()。dangerous不要重新傳遞最後一個Intent(do not redeliver the last intent)。相反,系統回調onStartCommand()時回傳一個空的Intent,除非有 pending intents傳遞,否則Intent將爲null。該模式適合做一些類似播放音樂的操作。
START_REDELIVER_INTENT:若系統在onStartCommand()執行並返回後kill了service,那麼service會被recreate並回調onStartCommand()並將最後一個Intent回傳至該方法。任何 pending intents都會被輪流傳遞。該模式適合做一些類似下載文件的操作。
START_STICKY_COMPATIBILITY
START_STICKY的兼容版本,但不保證服務被kill後一定能重啓。
而輸入參數flags正是代表此次onStartCommand()方法的啓動方式,正常啓動時,flags默認爲0,被kill後重新啓動,參數分爲以下兩種
- Service的生命週期方法onCreate、onStart、onBind等運行在哪個線程?
主線程,Service 中執行耗時操作會出現 anr