純粹是個(gè)人學(xué)習(xí)總結(jié),如有不對(duì)的地方請(qǐng)吐槽。
Service是一種在Android應(yīng)用后臺(tái)的一種組件,沒有自己的界面,不需要與用戶交互。
最基本的兩種用途:執(zhí)行長(zhǎng)時(shí)間時(shí)間運(yùn)行的耗時(shí)操作,如網(wǎng)絡(luò)下載,音樂播放,文件系統(tǒng)檢測(cè)。
一種是組件間的交互(通過將某些功能以Service組件的形式進(jìn)行封裝,然后提供給其他應(yīng)用組件調(diào)用,而不管這些組件是否與Service組件在同一進(jìn)程中)。
Service組件有兩種運(yùn)行模式,一種是啟動(dòng)模式,一種是綁定模式。
啟動(dòng)模式
如果Service組件是長(zhǎng)時(shí)間運(yùn)行的操作,則一般采用啟動(dòng)模式
啟動(dòng)模式的Service一般持續(xù)執(zhí)行一個(gè)單一的操作,Service被啟動(dòng)后,將一直處于運(yùn)行狀態(tài),即使調(diào)用startService的進(jìn)程結(jié)束了,Service仍然還存在,直到有進(jìn)程調(diào)用stopService,或者Service調(diào)用stopSelf自殺。
啟動(dòng)模式下,Service中的業(yè)務(wù)邏輯主要在onStartCommand方法中實(shí)現(xiàn),其中方法的返回值決定了Service的運(yùn)行模式。
1、START_NOT_STICKY:如果Sevice在啟動(dòng)后,被kill掉,并且沒有新啟動(dòng)的Intent傳給它,那么將Service移出啟動(dòng)狀態(tài)并且不重新生成,知道再次顯示調(diào)用Context.startService。適用場(chǎng)景:網(wǎng)上下載數(shù)據(jù)。
2、START_REDELIVER_INTENT:如果Service進(jìn)程在啟動(dòng)后kill掉,那么它將會(huì)被重啟,并且最后傳給他的Intent通過onStartCommand(Intent ,int,int)會(huì)被重新傳給他,這種模式保證了傳給它Intent一定會(huì)被處理完畢,適用場(chǎng)景:關(guān)鍵業(yè)務(wù)處理。
3、START_STICKY:如果Service在它啟動(dòng)后被kill掉,那么Android將讓Service繼續(xù)保持started狀態(tài),但是不保留啟動(dòng)它的Intent,Android將重新創(chuàng)建Service實(shí)例,并執(zhí)行onStartCommand方法,如果此時(shí)沒有新的Intent請(qǐng)求,此時(shí)Intent的參數(shù)是null,這一點(diǎn)要特別注意。適用場(chǎng)景:后臺(tái)播放音樂。這種運(yùn)行模式的特點(diǎn)是需要顯示啟動(dòng)并停止Service。
綁定模式
實(shí)例啟動(dòng)后,將調(diào)用onBind()方法,onBind方法返回給客戶端一個(gè)IBinder接口實(shí)例,IBinder允許客戶端回調(diào)Service方法,只要連接建立,Service就會(huì)一直運(yùn)行,(不管客戶是否保留Service的IBinder的引用)。通常IBinder是一個(gè)使用AIDL寫成的復(fù)雜接口
綁定模式下Service的生命周期:onCreate()--->onBind(只一次,不能多次綁定)---->onUnbind()--->onDestory()
兩種Service運(yùn)行模式不是完全隔離的,通過調(diào)用startService方法啟動(dòng)的Service對(duì)象實(shí)例也可以被其他進(jìn)程通過bindService方法來(lái)綁定,此時(shí),只有對(duì)Service實(shí)例既調(diào)用了stopService,也調(diào)用unbindService餓,這個(gè)Service才會(huì)結(jié)束
實(shí)現(xiàn)對(duì)Service組件功能的調(diào)用Service組件要做以下改造:
1、將Service組件的功能封裝到一個(gè)接口中。
2、實(shí)現(xiàn)一個(gè)內(nèi)部類,它繼承Bind類(既實(shí)現(xiàn)IBinder接口),并實(shí)現(xiàn)Service組件的功能接口類。
3、在Service組件的onBind方法中,返回步驟2的內(nèi)部類對(duì)象,供其他組件使用。
由于Service是在主線程運(yùn)行的,為避免產(chǎn)生應(yīng)用無(wú)響應(yīng)異常,必須在Service類的內(nèi)部創(chuàng)建一個(gè)單獨(dú)的線程,用于耗時(shí)的業(yè)務(wù)邏輯
IntentService:
我們或許會(huì)碰到這么一種業(yè)務(wù)需求,一項(xiàng)任務(wù)分成幾個(gè)子任務(wù),子任務(wù)按順序先后執(zhí)行,子任務(wù)全部執(zhí)行完后,這項(xiàng)任務(wù)才算成功,沒有一種簡(jiǎn)單的方法來(lái)處理這個(gè)過程呢,答案就是IntentService
IntentService是繼承于Service并處理異步請(qǐng)求的一個(gè)類,當(dāng)任務(wù)執(zhí)行完后,IntentService會(huì)自動(dòng)停止。可以啟動(dòng)IntentService多次,而每一個(gè)耗時(shí)操作會(huì)以工作隊(duì)列的方式在IntentService的onHandleIntent回調(diào)方法中執(zhí)行,并且,每次只會(huì)執(zhí)行一個(gè)工作線程,執(zhí)行完第一個(gè)再執(zhí)行第二個(gè)
IntentService(同時(shí)解決了多請(qǐng)求下線程同步的問題)。
1、在應(yīng)用的主線程外創(chuàng)建一個(gè)單獨(dú)的工作線程來(lái)執(zhí)行傳遞到onStartCommand方法的Intent組件。
2、創(chuàng)建一個(gè)工作隊(duì)列,它每次將一個(gè)Intent傳遞到onHandleIntent(),不需要考慮多線程的同步問題。
3、當(dāng)所有請(qǐng)求被處理完成后,將自動(dòng)停止服務(wù)而不需要顯示調(diào)用stopSelf方法。
4、提供一個(gè)返回null值的onBind方法的默認(rèn)實(shí)現(xiàn)。
5、提供了onStartCommand方法的默認(rèn)時(shí)間,它將所有的Intent發(fā)送到一個(gè)工作隊(duì)列,并進(jìn)一步發(fā)送到onHandleInteng方法。
Service不死:
1、service的進(jìn)程具有較高的優(yōu)先級(jí),如:android:priority = "1000"
2、onStartCommand方法,返回START_STICKY
3、在onDestroy方法里重啟service
4、一個(gè)不被殺死的進(jìn)程(android:allowBackup="true"),這個(gè)屬性不能亂設(shè)置或許是相當(dāng)于系統(tǒng)級(jí)的進(jìn)程
5、系統(tǒng)各種廣播監(jiān)聽,通過系統(tǒng)的廣播,監(jiān)聽并捕獲到,然后判斷是否需要重新啟動(dòng)service