Android IntentService源碼分析

題外話:我為什么特意寫呢,是因?yàn)槲襉PPO面試時(shí)候問(wèn)到了我intentservice有了解么,我當(dāng)時(shí)回答了有初步了解就是service的進(jìn)化版,然后內(nèi)部實(shí)現(xiàn)了異步處理的方式,最后我們不用管他的生命周期,任務(wù)結(jié)束后就會(huì)自行停止service,然后他們問(wèn)我源碼時(shí)候我懵了,所以回去后研究了下就打算寫出來(lái)

引言

Service服務(wù)是Android四大組件之一,在Android中有著舉足重輕的作用。Service服務(wù)是工作的UI線程中,當(dāng)你的應(yīng)用需要下載一個(gè)文件或者播放音樂(lè)等長(zhǎng)期處于后臺(tái)工作而有沒(méi)有UI界面的時(shí)候,你肯定要用到Service+Thread來(lái)實(shí)現(xiàn)。因此你需要自己在Service服務(wù)里面實(shí)現(xiàn)一個(gè)Thread工作線程來(lái)下載文件或者播放音樂(lè)。然而你每次都需要自己去寫一個(gè)Service+Thread來(lái)處理長(zhǎng)期處于后臺(tái)而沒(méi)有UI界面的任務(wù),這樣顯得很麻煩,沒(méi)必要每次都去構(gòu)建一個(gè)Service+Thread框架處理長(zhǎng)期處于后臺(tái)的任務(wù)。Google工程師給我們構(gòu)建了一個(gè)方便開(kāi)發(fā)者使用的這么一個(gè)框架---IntentService。我這邊一個(gè)項(xiàng)目是與硬件產(chǎn)品打交道的,需要打開(kāi)很多串口U口通信,但是很多設(shè)備如果都是使用時(shí)候打開(kāi)通道還是會(huì)出現(xiàn)打不開(kāi)的情況,所以我會(huì)在app啟動(dòng)的時(shí)候利用intentservice打開(kāi)全部設(shè)備,然后利用的是單例模式。

IntentService簡(jiǎn)介

IntentService是一個(gè)基礎(chǔ)類,用于處理Intent類型的異步任務(wù)請(qǐng)求。當(dāng)客戶端調(diào)用android.content.Context#startService(Intent)發(fā)送請(qǐng)求時(shí),Service服務(wù)被啟動(dòng),且在其內(nèi)部構(gòu)建一個(gè)工作線程來(lái)處理Intent請(qǐng)求。當(dāng)工作線程執(zhí)行結(jié)束,Service服務(wù)會(huì)自動(dòng)停止。IntentService是一個(gè)抽象類,用戶必須實(shí)現(xiàn)一個(gè)子類去繼承它,且必須實(shí)現(xiàn)IntentService里面的抽象方法onHandleIntent來(lái)處理異步任務(wù)請(qǐng)求。

使用方法

和正常Service一樣這里就不講述了

IntetService構(gòu)造函數(shù)


由此看到構(gòu)造函數(shù)只是傳入String,用于定義線程的名稱,然后看到一些成員變量可以看出IntentService其實(shí)只是封裝了Handler的一個(gè)異步線程的Service,具體看下onCreate()

IntentService#onCreate方法


看到這里大家應(yīng)該都知道了其內(nèi)部使用的是HandlerThread?類創(chuàng)建了一個(gè)循環(huán)的工作線程thread,然后將工作線程中的Looper對(duì)象作為參數(shù)來(lái)創(chuàng)建ServiceHandler消息執(zhí)行者。HandlerThread源碼分析及使用HandlerThread+Handler構(gòu)建成了一個(gè)帶有消息循環(huán)機(jī)制的異步任務(wù)處理機(jī)制。因此開(kāi)發(fā)者就可以將異步任務(wù)封裝成消息的形式發(fā)送到工作線程中去執(zhí)行了。Service服務(wù)生命周期第二步執(zhí)行IntentService#onStartCommand方法。

IntentService#onStartCommand方法


代碼很明確說(shuō)到會(huì)調(diào)用onStart方法,然后onStart方法內(nèi)部會(huì)利用mServiceHandler發(fā)送一個(gè)消息,這樣我們回顧之前的代碼可以看到


會(huì)調(diào)用onHandleIntent(msg.obj)方法,這個(gè)是抽象方法需要開(kāi)發(fā)者實(shí)現(xiàn),比如耗時(shí)的操作,最后調(diào)用stopSelf方法,然后在onDestroy方法,這個(gè)方法里面會(huì)調(diào)用mServiceLooper.quit();停止對(duì)消息的處理

IntentService總結(jié)

子類需繼承IntentService并且實(shí)現(xiàn)里面的onHandlerIntent抽象方法來(lái)處理intent類型的任務(wù)請(qǐng)求。

子類需要重寫默認(rèn)的構(gòu)造方法,且在構(gòu)造方法中調(diào)用父類帶參數(shù)的構(gòu)造方法。

IntentService類內(nèi)部利用HandlerThread+Handler構(gòu)建了一個(gè)帶有消息循環(huán)處理機(jī)制的后臺(tái)工作線程,客戶端只需調(diào)用Content#startService(Intent)將Intent任務(wù)請(qǐng)求放入后臺(tái)工作隊(duì)列中,且客戶端無(wú)需關(guān)注服務(wù)是否結(jié)束,非常適合一次性的后臺(tái)任務(wù)。比如瀏覽器下載文件,退出當(dāng)前瀏覽器之后,下載任務(wù)依然存在后臺(tái),直到下載文件結(jié)束,服務(wù)自動(dòng)銷毀。

只要當(dāng)前IntentService服務(wù)沒(méi)有被銷毀,客戶端就可以同時(shí)投放多個(gè)Intent異步任務(wù)請(qǐng)求,IntentService服務(wù)端這邊是順序執(zhí)行當(dāng)前后臺(tái)工作隊(duì)列中的Intent請(qǐng)求的,也就是每一時(shí)刻只能執(zhí)行一個(gè)Intent請(qǐng)求,直到該Intent處理結(jié)束才處理下一個(gè)Intent。因?yàn)镮ntentService類內(nèi)部利用HandlerThread+Handler構(gòu)建的是一個(gè)單線程來(lái)處理異步任務(wù)。

轉(zhuǎn)載于廢墟的樹(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容