一氛雪、Service 簡(jiǎn)介
Service 是 Android 程序中四大基礎(chǔ)組件之一几莽,它和 Activity一樣都是 Context 的子類腾仅,只不過(guò)它沒(méi)有 UI 界面力惯,是在后臺(tái)運(yùn)行的組件跑筝。
Service 是 Android 中實(shí)現(xiàn)程序后臺(tái)運(yùn)行的解決方案死讹,它非常適用于去執(zhí)行那些不需要和用戶交互而且還要求長(zhǎng)期運(yùn)行的任務(wù)。Service 默認(rèn)并不會(huì)運(yùn)行在子線程中曲梗,它也不運(yùn)行在一個(gè)獨(dú)立的進(jìn)程中赞警,它同樣執(zhí)行在 UI 線程中,因此虏两,不要在 Service 中執(zhí)行耗時(shí)的操作愧旦,除非你在 Service 中創(chuàng)建了子線程來(lái)完成耗時(shí)操作。
二定罢、Service 種類
按運(yùn)行地點(diǎn)分類:
類別 | 區(qū)別 | 優(yōu)點(diǎn) | 缺點(diǎn) | 應(yīng)用 |
---|---|---|---|---|
本地服務(wù)(Local Service) | 該服務(wù)依附在主進(jìn)程上 | 服務(wù)依附在主進(jìn)程上而不是獨(dú)立的進(jìn)程笤虫,這樣在一定程度上節(jié)約了資源,另外 Local 服務(wù)因?yàn)槭窃谕贿M(jìn)程因此不需要 IPC,也不需要 AIDL琼蚯。相應(yīng) bindService 方便很多酬凳。 | 主進(jìn)程被 Kill 后,服務(wù)便會(huì)終止遭庶。 | 如:音樂(lè)播放器播放等不需要常駐的服務(wù)宁仔。 |
遠(yuǎn)程服務(wù)(Remote Service) | 該服務(wù)是獨(dú)立的進(jìn)程 | 服務(wù)為獨(dú)立的進(jìn)程,對(duì)應(yīng)進(jìn)程名格式為所在包名加上你指定的 android:process 字符串罚拟。由于是獨(dú)立的進(jìn)程台诗,因此在 Activity 所在進(jìn)程被 kill 的時(shí)候完箩,該服務(wù)依然在運(yùn)行赐俗,不受其他進(jìn)程影響,有利于為多個(gè)進(jìn)程提供服務(wù)具有較高的靈活性弊知。 | 該服務(wù)是獨(dú)立的進(jìn)程阻逮,會(huì)占用一定資源,并且使用 AIDL 進(jìn)行 IPC 稍微麻煩一點(diǎn)秩彤。 | 一些提供系統(tǒng)服務(wù)的 Service叔扼,這種 Service 是常駐的。 |
按運(yùn)行類型分類:
類別 | 區(qū)別 | 應(yīng)用 |
---|---|---|
前臺(tái)服務(wù) | 會(huì)在通知欄顯示 onGoing 的 Notification | 當(dāng)服務(wù)被終止的時(shí)候漫雷,通知一欄的 Notification 也會(huì)消失瓜富,這樣對(duì)于用戶有一定的通知作用。常見(jiàn)的如音樂(lè)播放服務(wù)降盹。 |
后臺(tái)服務(wù) | 默認(rèn)的服務(wù)即為后臺(tái)服務(wù)与柑,即不會(huì)在通知一欄顯示 onGoing 的 Notification。 | 當(dāng)服務(wù)被終止的時(shí)候蓄坏,用戶是看不到效果的价捧。某些不需要運(yùn)行或終止提示的服務(wù),如天氣更新涡戳,日期同步结蟋,郵件同步等。 |
按使用方式分類:
類別 | 區(qū)別 |
---|---|
startService 啟動(dòng)的服務(wù) | 主要用于啟動(dòng)一個(gè)服務(wù)執(zhí)行后臺(tái)任務(wù)渔彰,不進(jìn)行通信嵌屎。停止服務(wù)使用 stopService。 |
bindService 啟動(dòng)的服務(wù) | 方法啟動(dòng)的服務(wù)要進(jìn)行通信恍涂。停止服務(wù)使用 unbindService编整。 |
同時(shí)使用 startService、bindService 啟動(dòng)的服務(wù) | 停止服務(wù)應(yīng)同時(shí)使用 stopService 與 unbindService |
三乳丰、Service 生命周期
onCreate():
系統(tǒng)在 Service 第一次創(chuàng)建時(shí)執(zhí)行此方法掌测,來(lái)執(zhí)行只運(yùn)行一次的初始化工作。如果 service 已經(jīng)運(yùn)行,這個(gè)方法不會(huì)被調(diào)用汞斧。
onStartCommand():
每次客戶端調(diào)用 startService() 方法啟動(dòng)該 Service 都會(huì)回調(diào)該方法(多次調(diào)用)夜郁。一旦這個(gè)方法執(zhí)行,service 就啟動(dòng)并且在后臺(tái)長(zhǎng)期運(yùn)行粘勒。通過(guò)調(diào)用 stopSelf() 或 stopService() 來(lái)停止服務(wù)竞端。
onBind():
當(dāng)組件調(diào)用 bindService() 想要綁定到 service 時(shí)(比如想要執(zhí)行進(jìn)程間通訊)系統(tǒng)調(diào)用此方法(一次調(diào)用,一旦綁定后庙睡,下次再調(diào)用 bindService() 不會(huì)回調(diào)該方法)事富。在你的實(shí)現(xiàn)中,你必須提供一個(gè)返回一個(gè) IBinder 來(lái)以使客戶端能夠使用它與 service 通訊乘陪,你必須總是實(shí)現(xiàn)這個(gè)方法统台,但是如果你不允許綁定,那么你應(yīng)返回 null啡邑。
onUnbind():
當(dāng)前組件調(diào)用 unbindService()贱勃,想要解除與 Service 的綁定時(shí)系統(tǒng)調(diào)用此方法(一次調(diào)用,一旦解除綁定后谤逼,下次再調(diào)用 unbindService() 會(huì)拋出異常)贵扰。
onDestory():
系統(tǒng)在 Service 不再被使用并且銷毀時(shí)調(diào)用此方法(一次調(diào)用)。service 應(yīng)在此方法中釋放資源流部,比如線程戚绕、已注冊(cè)的監(jiān)聽(tīng)器、接收器等等枝冀,這是 service 收到的最后一個(gè)調(diào)用舞丛。
三種不同情況下 Service 的生命周期情況:
- startService / stopService
生命周期順序:onCreate() -> onStartCommand() -> onDestroy()
如果一個(gè) Service 被某個(gè) Activity 調(diào)用 Context.startService() 方法啟動(dòng),那么不管是否有 Activity 使用 bindService 綁定或 unbindService 解除綁定到該 Service宾茂,該 Service 都在后臺(tái)運(yùn)行瓷马,直到被調(diào)用 stopService,或自身的 stopSelf 方法跨晴。當(dāng)然如果系統(tǒng)資源不足欧聘,Android 系統(tǒng)也可能結(jié)束服務(wù),還有一種方法可以關(guān)閉服務(wù)端盆,在設(shè)置中怀骤,通過(guò)應(yīng)用 -> 找到自己應(yīng)用 -> 停止。
注意點(diǎn):
(1)第一次 startService 會(huì)觸發(fā) onCreate() 和 onStartCommand焕妙,以后在服務(wù)運(yùn)行過(guò)程中蒋伦,每次 startService 都只會(huì)觸發(fā) onStartCommand。
(2)不論 startService 多少次焚鹊,stopService 一次就會(huì)停止服務(wù)
- bindService / unbindService
生命周期順序:onCreate -> onBind -> onUnBind -> onDestory
如果一個(gè) Service 被某個(gè) Activity 中調(diào)用 bindService 方法啟動(dòng)痕届,不論 bindService 被調(diào)用幾次,Service 的 onCreate 方法只會(huì)執(zhí)行一次,同時(shí) onStartCommand 方法始終不會(huì)調(diào)用研叫。
當(dāng)建立連接后锤窑,Service 會(huì)一直