Service,四大組件之一,用很多熙卡,但是對(duì)其理解還不是很全面≌人ⅲ現(xiàn)在我們聊聊關(guān)于Service這個(gè)組件。雖然不是很詳細(xì)驳癌,但是知識(shí)點(diǎn)比較全面滑燃。
Service是什么
網(wǎng)上都說(shuō),Service是是處理一些耗時(shí)的邏輯颓鲜,或者執(zhí)行長(zhǎng)期運(yùn)行的任務(wù)表窘。不錯(cuò),但是如果直接在onCreate()或者onStart()直接執(zhí)行耗時(shí)操作甜滨,那有你好受的了乐严。為什么?下面再說(shuō)衣摩。
Service啟動(dòng)方式
1.startService
不能Activity直接通信昂验,可用Broadcast機(jī)制通知Activity更新,不會(huì)隨著Activity的finish而stop艾扮,需要我們手動(dòng)去stop既琴,或者內(nèi)存不足,系統(tǒng)去stop
2.bindService
可以直接和Activity通信泡嘴,會(huì)隨著應(yīng)用的關(guān)閉而stop
Service的生命周期
onCreate onStart onDestroy onBind
1). 被啟動(dòng)的服務(wù)的生命周期
如果一個(gè)Service被某個(gè)Activity 調(diào)用 Context.startService 方法啟動(dòng)呛梆,那么不管是否有Activity使用bindService綁定或unbindService解除綁定到該Service,該Service都在后臺(tái)運(yùn)行磕诊。如果一個(gè)Service被startService 方法多次啟動(dòng),那么onCreate方法只會(huì)調(diào)用一次纹腌,onStart將會(huì)被調(diào)用多次(對(duì)應(yīng)調(diào)用startService的次數(shù))霎终,并且系統(tǒng)只會(huì)創(chuàng)建Service的一個(gè)實(shí)例(因此你應(yīng)該知道只需要一次stopService調(diào)用)。該Service將會(huì)一直在后臺(tái)運(yùn)行升薯,而不管對(duì)應(yīng)程序的Activity是否在運(yùn)行莱褒,直到被調(diào)用stopService,或自身的stopSelf方法涎劈。當(dāng)然如果系統(tǒng)資源不足广凸,android系統(tǒng)也可能結(jié)束服務(wù)。
2). 被綁定的服務(wù)的生命周期
如果一個(gè)Service被某個(gè)Activity 調(diào)用 Context.bindService 方法綁定啟動(dòng)蛛枚,不管調(diào)用 bindService 調(diào)用幾次谅海,onCreate方法都只會(huì)調(diào)用一次,同時(shí)onStart方法始終不會(huì)被調(diào)用蹦浦。當(dāng)連接建立之后扭吁,Service將會(huì)一直運(yùn)行,除非調(diào)用Context.unbindService 斷開(kāi)連接或者之前調(diào)用bindService 的 Context 不存在了(如Activity被finish的時(shí)候),系統(tǒng)將會(huì)自動(dòng)停止Service侥袜,對(duì)應(yīng)onDestroy將被調(diào)用蝌诡。
3). 被啟動(dòng)又被綁定的服務(wù)的生命周期
如果一個(gè)Service又被啟動(dòng)又被綁定,則該Service將會(huì)一直在后臺(tái)運(yùn)行枫吧。并且不管如何調(diào)用浦旱,onCreate始終只會(huì)調(diào)用一次,對(duì)應(yīng)startService調(diào)用多少次九杂,Service的onStart便會(huì)調(diào)用多少次颁湖。調(diào)用unbindService將不會(huì)停止Service,而必須調(diào)用 stopService 或 Service的 stopSelf 來(lái)停止服務(wù)尼酿。
Service與Thread
很多時(shí)候爷狈,你可能會(huì)問(wèn),為什么要用 Service裳擎,而不用 Thread 呢涎永,因?yàn)橛?Thread 是很方便的,比起 Service 也方便多了鹿响,下面我詳細(xì)的來(lái)解釋一下羡微。
1). Thread
Thread 是程序執(zhí)行的最小單元,它是分配CPU的基本單位惶我÷杈螅可以用 Thread 來(lái)執(zhí)行一些異步的操作。
2). Service
Service 是android的一種機(jī)制绸贡,當(dāng)它運(yùn)行的時(shí)候如果是Local Service盯蝴,那么對(duì)應(yīng)的 Service 是運(yùn)行在主進(jìn)程的 main 線程上的。如:onCreate听怕,onStart 這些函數(shù)在被系統(tǒng)調(diào)用的時(shí)候都是在主進(jìn)程的 main 線程上運(yùn)行的捧挺。如果是RemoteService,那么對(duì)應(yīng)的 Service 則是運(yùn)行在獨(dú)立進(jìn)程的 main 線程上尿瞭。因此請(qǐng)不要把 Service 理解成線程闽烙,它跟線程半毛錢的關(guān)系都沒(méi)有!
所以我們不能把耗時(shí)的操作放在Service的onCreate()或者onStart()上了声搁,很容易報(bào)ANR黑竞。
既然這樣,那么我們?yōu)槭裁匆?Service 呢疏旨?其實(shí)這跟 android 的系統(tǒng)機(jī)制有關(guān)很魂,我們先拿 Thread 來(lái)說(shuō)。Thread 的運(yùn)行是獨(dú)立于 Activity 的檐涝,也就是說(shuō)當(dāng)一個(gè) Activity 被 finish 之后莫换,如果你沒(méi)有主動(dòng)停止 Thread 或者 Thread 里的 run 方法沒(méi)有執(zhí)行完畢的話霞玄,Thread 也會(huì)一直執(zhí)行。因此這里會(huì)出現(xiàn)一個(gè)問(wèn)題:當(dāng) Activity 被 finish 之后拉岁,你不再持有該 Thread 的引用坷剧。另一方面,你沒(méi)有辦法在不同的 Activity 中對(duì)同一 Thread 進(jìn)行控制喊暖。
舉個(gè)例子:如果你的 Thread 需要不停地隔一段時(shí)間就要連接服務(wù)器做某種同步的話惫企,該 Thread 需要在 Activity 沒(méi)有start的時(shí)候也在運(yùn)行。這個(gè)時(shí)候當(dāng)你 start 一個(gè) Activity 就沒(méi)有辦法在該 Activity 里面控制之前創(chuàng)建的 Thread陵叽。因此你便需要?jiǎng)?chuàng)建并啟動(dòng)一個(gè) Service 狞尔,在 Service 里面創(chuàng)建、運(yùn)行并控制該 Thread巩掺,這樣便解決了該問(wèn)題(因?yàn)槿魏?Activity 都可以控制同一 Service偏序,而系統(tǒng)也只會(huì)創(chuàng)建一個(gè)對(duì)應(yīng) Service 的實(shí)例)。