Service基礎(chǔ)用法
服務(wù)(service)是一種可在后臺(tái)執(zhí)行長(zhǎng)時(shí)間操作而不提供界面的應(yīng)用組件,由應(yīng)用的組件啟動(dòng)捺宗,而且即使用戶(hù)切換到其他應(yīng)用柱蟀,服務(wù)仍將在后臺(tái)繼續(xù)運(yùn)行。服務(wù)默認(rèn)運(yùn)行在其托管進(jìn)程的主線(xiàn)程中蚜厉,因此如果需要在服務(wù)中執(zhí)行耗時(shí)或者阻斷性操作长已,需要使用單獨(dú)的線(xiàn)程或者使用系統(tǒng)提供的IntentService
。一般情況下,如果需要執(zhí)行的任務(wù)只有在用戶(hù)與應(yīng)用交互時(shí)才需要執(zhí)行术瓮,則首先應(yīng)考慮使用線(xiàn)程康聂,而不是服務(wù)。
服務(wù)的類(lèi)型
- 前臺(tái)服務(wù)胞四,前臺(tái)服務(wù)可以用來(lái)執(zhí)行一些用戶(hù)能注意到的操作恬汁,例如播放音樂(lè),前臺(tái)服務(wù)必須顯示
通知
辜伟,即使用戶(hù)停止與應(yīng)用的交互氓侧,前臺(tái)服務(wù)仍會(huì)繼續(xù)運(yùn)行。 - 后臺(tái)服務(wù)导狡,用來(lái)執(zhí)行用戶(hù)不會(huì)直接注意到的操作约巷,例如壓縮清理應(yīng)用緩存。
- 綁定服務(wù)旱捧,當(dāng)應(yīng)用組件通過(guò)
bindService
綁定到服務(wù)時(shí)独郎,服務(wù)即處于綁定狀態(tài),綁定服務(wù)會(huì)提供C/S接口與應(yīng)用組件進(jìn)行通信廊佩,一個(gè)服務(wù)可以同時(shí)被多個(gè)組件綁定囚聚,當(dāng)全部取消綁定后,服務(wù)才會(huì)被銷(xiāo)毀标锄。
創(chuàng)建并使用服務(wù)
可以通過(guò)創(chuàng)建 Service
的子類(lèi)來(lái)使用服務(wù),在子類(lèi)中需要實(shí)現(xiàn)一些方法來(lái)處理服務(wù)的生命周期茁计,一般情況下需要重寫(xiě)以下方法:
方法名 | 描述 |
---|---|
onCreate | 首次創(chuàng)建服務(wù)時(shí)料皇,系統(tǒng)會(huì)(在調(diào)用 onStartCommand() 或 onBind() 之前)調(diào)用此方法來(lái)執(zhí)行一次性設(shè)置程序。如果服務(wù)已在運(yùn)行星压,則不會(huì)調(diào)用此方法践剂。 |
onBind | 當(dāng)另一個(gè)組件想要與服務(wù)綁定(例如執(zhí)行 RPC)時(shí),系統(tǒng)會(huì)通過(guò)調(diào)用 bindService() 來(lái)調(diào)用此方法娜膘。在此方法的實(shí)現(xiàn)中逊脯,必須通過(guò)返回 IBinder 提供一個(gè)接口,以供客戶(hù)端用來(lái)與服務(wù)進(jìn)行通信竣贪。如果并不希望服務(wù)被綁定军洼,可以直接返回 null。 |
onUnbind | 所有與當(dāng)前服務(wù)綁定的客戶(hù)端調(diào)用了解綁方法后調(diào)用 |
onStartCommand | 當(dāng)另一個(gè)組件(如 Activity)請(qǐng)求啟動(dòng)服務(wù)時(shí)演怎,系統(tǒng)會(huì)通過(guò)調(diào)用 startService() 來(lái)調(diào)用此方法匕争。執(zhí)行此方法時(shí),服務(wù)即會(huì)啟動(dòng)并可在后臺(tái)無(wú)限期運(yùn)行爷耀。如果實(shí)現(xiàn)了此方法甘桑,則在服務(wù)工作完成后,需通過(guò)調(diào)用 stopSelf() 或 stopService() 來(lái)停止服務(wù)。(如果只想提供綁定跑杭,則無(wú)需實(shí)現(xiàn)此方法铆帽。) |
onDestory | 當(dāng)不再使用服務(wù)且準(zhǔn)備將其銷(xiāo)毀時(shí),系統(tǒng)會(huì)調(diào)用此方法德谅。服務(wù)應(yīng)通過(guò)實(shí)現(xiàn)此方法來(lái)清理任何資源锄贼,如線(xiàn)程、注冊(cè)的偵聽(tīng)器女阀、接收器等宅荤。這是服務(wù)接收的最后一個(gè)調(diào)用。 |
通辰撸可以擴(kuò)展以下兩個(gè)類(lèi)來(lái)創(chuàng)建啟動(dòng)服務(wù)
- Service冯键,這是所有服務(wù)的基類(lèi),默認(rèn)運(yùn)行在應(yīng)用的主線(xiàn)程中庸汗,需要自己創(chuàng)建并維護(hù)工作線(xiàn)程惫确。
class CustomService:Service() {
private val TAG = "CustomService"
override fun onCreate() {
Log.d(TAG, "onCreate")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand")
return super.onStartCommand(intent, flags, startId)
}
override fun onBind(intent: Intent?): IBinder? {
Log.d(TAG, "onBind")
return null
}
override fun onDestroy() {
Log.d(TAG, "onBind")
super.onDestroy()
}
}
- IntentService,這是Service的子類(lèi)蚯舱,內(nèi)部維護(hù)了一個(gè)工作線(xiàn)程(HandlerThread)通過(guò)隊(duì)列的方式串行的處理所有啟動(dòng)請(qǐng)求(onStartCommand方法)改化,將其轉(zhuǎn)發(fā)到
onHandleIntent
方法,提供了onBind
的默認(rèn)實(shí)現(xiàn)返回null枉昏,一般情況下更推薦使用此類(lèi)來(lái)使用服務(wù)陈肛。例如:
class CustomIntentService(private val name: String) : IntentService(name) {
private val TAG = "CustomIntentService"
override fun onHandleIntent(intent: Intent?) {
Log.d(TAG, "onHandleIntent")
}
}
服務(wù)的生命周期
由上圖可見(jiàn),服務(wù)的生命周期兄裂,主要有兩種情況:
-
啟動(dòng)服務(wù)句旱,由其他組件調(diào)用
startService
創(chuàng)建,然后無(wú)限期運(yùn)行晰奖,可以通過(guò)服務(wù)自己調(diào)用stopSelf()
或者其他組件通過(guò)調(diào)用stopService
來(lái)停止服務(wù)谈撒,服務(wù)停止后,系統(tǒng)會(huì)將其銷(xiāo)毀匾南。
image.png -
綁定服務(wù)啃匿,有其他組件(客戶(hù)端)調(diào)用
bindService
創(chuàng)建,客戶(hù)端可通過(guò)IBinder
接口與服務(wù)進(jìn)行通信蛆楞,通過(guò)調(diào)用unbindService
關(guān)閉連接溯乒,多個(gè)客戶(hù)端可綁定相同的服務(wù),在所有客戶(hù)端解綁之前臊岸,調(diào)用stopSelf()
和stopService
實(shí)際不會(huì)停止服務(wù)橙数。
image.png -
啟動(dòng)&綁定 混合使用,當(dāng)一個(gè)服務(wù)同時(shí)被啟動(dòng)和綁定時(shí)帅戒,單獨(dú)的停止服務(wù)和解綁操作都不會(huì)使服務(wù)停止灯帮,必須所有客戶(hù)端解綁和停止服務(wù)的方法被調(diào)用兩個(gè)條件都滿(mǎn)足服務(wù)才會(huì)停止崖技。
image.png