純粹是個(gè)人學(xué)習(xí)總結(jié)屈雄,如有不對(duì)的地方請(qǐng)吐槽泊愧。
Service是一種在Android應(yīng)用后臺(tái)的一種組件伊磺,沒(méi)有自己的界面,不需要與用戶(hù)交互删咱。
最基本的兩種用途:執(zhí)行長(zhǎng)時(shí)間時(shí)間運(yùn)行的耗時(shí)操作屑埋,如網(wǎng)絡(luò)下載,音樂(lè)播放痰滋,文件系統(tǒng)檢測(cè)摘能。
一種是組件間的交互(通過(guò)將某些功能以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掉,并且沒(méi)有新啟動(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通過(guò)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í)沒(méi)有新的Intent請(qǐng)求彤路,此時(shí)Intent的參數(shù)是null,這一點(diǎn)要特別注意芥映。適用場(chǎng)景:后臺(tái)播放音樂(lè)洲尊。這種運(yùn)行模式的特點(diǎn)是需要顯示啟動(dòng)并停止Service远豺。
綁定模式
實(shí)例啟動(dòng)后,將調(diào)用onBind()方法坞嘀,onBind方法返回給客戶(hù)端一個(gè)IBinder接口實(shí)例躯护,IBinder允許客戶(hù)端回調(diào)Service方法,只要連接建立丽涩,Service就會(huì)一直運(yùn)行棺滞,(不管客戶(hù)是否保留Service的IBinder的引用)。通常IBinder是一個(gè)使用AIDL寫(xiě)成的復(fù)雜接口
綁定模式下Service的生命周期:onCreate()--->onBind(只一次矢渊,不能多次綁定)---->onUnbind()--->onDestory()
兩種Service運(yùn)行模式不是完全隔離的继准,通過(guò)調(diào)用startService方法啟動(dòng)的Service對(duì)象實(shí)例也可以被其他進(jìn)程通過(guò)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)部類(lèi)猪瞬,它繼承Bind類(lèi)(既實(shí)現(xiàn)IBinder接口)憎瘸,并實(shí)現(xiàn)Service組件的功能接口類(lèi)。
3撑螺、在Service組件的onBind方法中含思,返回步驟2的內(nèi)部類(lèi)對(duì)象,供其他組件使用甘晤。
由于Service是在主線(xiàn)程運(yùn)行的含潘,為避免產(chǎn)生應(yīng)用無(wú)響應(yīng)異常,必須在Service類(lèi)的內(nèi)部創(chuàng)建一個(gè)單獨(dú)的線(xiàn)程线婚,用于耗時(shí)的業(yè)務(wù)邏輯
IntentService:
我們或許會(huì)碰到這么一種業(yè)務(wù)需求遏弱,一項(xiàng)任務(wù)分成幾個(gè)子任務(wù),子任務(wù)按順序先后執(zhí)行塞弊,子任務(wù)全部執(zhí)行完后漱逸,這項(xiàng)任務(wù)才算成功,沒(méi)有一種簡(jiǎn)單的方法來(lái)處理這個(gè)過(guò)程呢游沿,答案就是IntentService
IntentService是繼承于Service并處理異步請(qǐng)求的一個(gè)類(lèi)饰抒,當(dāng)任務(wù)執(zhí)行完后,IntentService會(huì)自動(dòng)停止诀黍〈樱可以啟動(dòng)IntentService多次,而每一個(gè)耗時(shí)操作會(huì)以工作隊(duì)列的方式在IntentService的onHandleIntent回調(diào)方法中執(zhí)行眯勾,并且枣宫,每次只會(huì)執(zhí)行一個(gè)工作線(xiàn)程婆誓,執(zhí)行完第一個(gè)再執(zhí)行第二個(gè)
IntentService(同時(shí)解決了多請(qǐng)求下線(xiàn)程同步的問(wèn)題)。
1也颤、在應(yīng)用的主線(xiàn)程外創(chuàng)建一個(gè)單獨(dú)的工作線(xiàn)程來(lái)執(zhí)行傳遞到onStartCommand方法的Intent組件洋幻。
2、創(chuàng)建一個(gè)工作隊(duì)列翅娶,它每次將一個(gè)Intent傳遞到onHandleIntent()文留,不需要考慮多線(xiàn)程的同步問(wèn)題。
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)介衔,通過(guò)系統(tǒng)的廣播恨胚,監(jiān)聽(tīng)并捕獲到,然后判斷是否需要重新啟動(dòng)service