一、Service簡介
Service是Android程序中四大基礎(chǔ)組件之一,它和Activity一樣都是Context的子類,
只不過它沒有UI界面,是在后臺運行的組件。
Service是Android中實現(xiàn)程序后臺運行的解決方案,它非常適用于去執(zhí)行那些不需
要和用戶交互而且還要求長期運行的任務(wù)。Service默認(rèn)并不會運行在子線程中,它
也不運行在一個獨立的進(jìn)程中,它同樣執(zhí)行在UI線程中,因此,不要在Service中執(zhí)
行耗時的操作,除非你在Service中創(chuàng)建了子線程來完成耗時操作。
二、Service種類
按運行地點分類:

按運行類型分類:

按使用方式分類:

三、Service生命周期

OnCreate()
系統(tǒng)在service第一次創(chuàng)建時執(zhí)行此方法,來執(zhí)行只運行一次的初始化工作。如果
service已經(jīng)運行,這個方法不會被調(diào)用。
onStartCommand()
每次客戶端調(diào)用startService()方法啟動該Service都會回調(diào)該方法(多次調(diào)用)。一
旦這個方法執(zhí)行,service就啟動并且在后臺長期運行。通過調(diào)用stopSelf()或
stopService()來停止服務(wù)。
OnBind()
當(dāng)組件調(diào)用bindService()想要綁定到service時(比如想要執(zhí)行進(jìn)程間通訊)系統(tǒng)調(diào)用
此方法(一次調(diào)用,一旦綁定后,下次再調(diào)用bindService()不會回調(diào)該方法)。在
你的實現(xiàn)中,你必須提供一個返回一個IBinder來以使客戶端能夠使用它與service通
訊,你必須總是實現(xiàn)這個方法,但是如果你不允許綁定,那么你應(yīng)返回null。
OnUnbind()
當(dāng)前組件調(diào)用unbindService(),想要解除與service的綁定時系統(tǒng)調(diào)用此方法(一次
調(diào)用,一旦解除綁定后,下次再調(diào)用unbindService()會拋出異常)。
OnDestory()
系統(tǒng)在service不再被使用并要銷毀時調(diào)用此方法(一次調(diào)用)。service應(yīng)在此方法
中釋放資源,比如線程,已注冊的偵聽器,接收器等等.這是service收到的最后一
個調(diào)用。
下面是三種不同情況下Service的生命周期情況。
1.startService / stopService
生命周期順序:onCreate->onStartCommand->onDestroy
如果一個Service被某個Activity 調(diào)用 Context.startService方法啟動,那么不管是否
有Activity使用bindService綁定或unbindService解除綁定到該Service,該Service都
在后臺運行,直到被調(diào)用stopService,或自身的stopSelf方法。當(dāng)然如果系統(tǒng)資源
不足,android系統(tǒng)也可能結(jié)束服務(wù),還有一種方法可以關(guān)閉服務(wù),在設(shè)置中,通過
應(yīng)用->找到自己應(yīng)用->停止。
注意點:
①第一次 startService 會觸發(fā) onCreate 和 onStartCommand,以后在服務(wù)運行過
程中,每次 startService 都只會觸發(fā) onStartCommand
②不論 startService 多少次,stopService 一次就會停止服務(wù)
2.bindService / unbindService
生命周期順序:onCreate->onBind->onUnBind->onDestroy
如果一個Service在某個Activity中被調(diào)用bindService方法啟動,不論bindService被
調(diào)用幾次,Service的onCreate方法只會執(zhí)行一次,同時onStartCommand方法始終
不會調(diào)用。
當(dāng)建立連接后,Service會一直運行,除非調(diào)用unbindService來解除綁定、斷開連
接或調(diào)用該Service的Context不存在了(如Activity被Finish——即通過bindService
啟動的Service的生命周期依附于啟動它的Context),系統(tǒng)在這時會自動停止該
Service。
注意點:
第一次 bindService 會觸發(fā) onCreate 和 onBind,以后在服務(wù)運行過程中,每次
bindService 都不會觸發(fā)任何回調(diào)
3.混合型(上面兩種方式的交互)
當(dāng)一個Service在被啟動(startService)的同時又被綁定(bindService),該Service將
會一直在后臺運行,并且不管調(diào)用幾次,onCreate方法始終只會調(diào)用一次,
onStartCommand的調(diào)用次數(shù)與startService調(diào)用的次數(shù)一致(使用bindService方法
不會調(diào)用onStartCommand)。同時,調(diào)用unBindService將不會停止Service,必
須調(diào)用stopService或Service自身的stopSelf來停止服務(wù)。
在什么情況下使用 startService 或 bindService 或 同時使用startService 和 bindService?
①如果你只是想要啟動一個后臺服務(wù)長期進(jìn)行某項任務(wù)那么使用 startService 便可
以了。
②如果你想要與正在運行的 Service 取得聯(lián)系,那么有兩種方法,一種是使用
broadcast ,另外是使用 bindService ,前者的缺點是如果交流較為頻繁,容易造
成性能上的問題,并且 BroadcastReceiver 本身執(zhí)行代碼的時間是很短的(也許執(zhí)
行到一半,后面的代碼便不會執(zhí)行),而后者則沒有這些問題,因此我們肯定選擇
使用 bindService(這個時候你便同時在使用 startService 和 bindService 了,這在
Activity 中更新 Service 的某些運行狀態(tài)是相當(dāng)有用的)。
③如果你的服務(wù)只是公開一個遠(yuǎn)程接口,供連接上的客服端(android 的 Service
是C/S架構(gòu))遠(yuǎn)程調(diào)用執(zhí)行方法。這個時候你可以不讓服務(wù)一開始就運行,而只用
bindService ,這樣在第一次 bindService 的時候才會創(chuàng)建服務(wù)的實例運行它,這會
節(jié)約很多系統(tǒng)資源,特別是如果你的服務(wù)是Remote Service,那么該效果會越明顯
(當(dāng)然在 Service 創(chuàng)建的時候會花去一定時間,你應(yīng)當(dāng)注意到這點)
一般面試官問到兩種啟動方式的區(qū)別,可以這么回答
startService只是啟動Service,啟動它的組件(如Activity)和Service并沒有關(guān)聯(lián),只有當(dāng)Service調(diào)用stopSelf或者其他組件調(diào)用stopService服務(wù)才會終止。
bindService方法啟動Service,其他組件可以通過回調(diào)獲取Service的代理對象和Service交互,而這兩方也進(jìn)行了綁定,當(dāng)啟動方銷毀時,Service也會自動進(jìn)行unBind操作,當(dāng)發(fā)現(xiàn)所有綁定都進(jìn)行了unBind時才會銷毀Service。