Service詳解-創(chuàng)新互聯(lián)

service可以在和多場(chǎng)合的應(yīng)用中使用,比如播放多媒體的時(shí)候用戶(hù)啟動(dòng)了其他Activity這個(gè)時(shí)候程序要在后臺(tái)繼續(xù)播放,比如檢測(cè)SD卡上文件的變化,再或者在后臺(tái)記錄你地理信息位置的改變等等,總之服務(wù)嘛,總是藏在后頭的。

公司主營(yíng)業(yè)務(wù):網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶(hù)真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶(hù)帶來(lái)驚喜。創(chuàng)新互聯(lián)推出開(kāi)陽(yáng)免費(fèi)做網(wǎng)站回饋大家。

Service是在一段不定的時(shí)間運(yùn)行在后臺(tái),不和用戶(hù)交互應(yīng)用組件。每個(gè)Service必須在manifest中 通過(guò)<service>來(lái)聲明??梢酝ㄟ^(guò)contect.startservice和contect.bindserverice來(lái)啟動(dòng)。

Service和其他的應(yīng)用組件一樣,運(yùn)行在進(jìn)程的主線(xiàn)程中。這就是說(shuō)如果service需要很多耗時(shí)或者阻塞的操作,需要在其子線(xiàn)程中實(shí)現(xiàn)。

service的兩種模式(startService()/bindService()不是完全分離的):

  Context.startService(Intent intent)

  Context.bindService(Intent intent, ServiceConnection conn, int flags)

  stopService(Intent intent)

  unbindService(ServiceConnection conn)

  1. 使用startService()方法啟用服務(wù),調(diào)用者與服務(wù)之間沒(méi)有關(guān)連,即使調(diào)用者退出了,服務(wù)仍然運(yùn)行。

  2. 使用bindService()方法啟用服務(wù),調(diào)用者與服務(wù)綁定在了一起,調(diào)用者一旦退出,服務(wù)也就終止,大有“不求同時(shí)生,必須同時(shí)死”的特點(diǎn)。

----------------------------------------------------------

本地服務(wù) Local Service 用于應(yīng)用程序內(nèi)部。

  它可以啟動(dòng)并運(yùn)行,直至有人停止了它或它自己停止。在這種方式下,它以調(diào)用Context.startService()啟動(dòng),而以調(diào)用Context.stopService()結(jié)束。它可以調(diào)用Service.stopSelf() 或 Service.stopSelfResult()來(lái)自己停止。不論調(diào)用了多少次startService()方法,你只需要調(diào)用一次stopService()來(lái)停止服務(wù)。

用于實(shí)現(xiàn)應(yīng)用程序自己的一些耗時(shí)任務(wù),比如查詢(xún)升級(jí)信息,并不占用應(yīng)用程序比如Activity所屬線(xiàn)程,而是單開(kāi)線(xiàn)程后臺(tái)執(zhí)行,這樣用戶(hù)體驗(yàn)比較好。

遠(yuǎn)程服務(wù) Remote Service 用于android系統(tǒng)內(nèi)部的應(yīng)用程序之間。

  它可以通過(guò)自己定義并暴露出來(lái)的接口進(jìn)行程序操作??蛻?hù)端建立一個(gè)到服務(wù)對(duì)象的連接,并通過(guò)那個(gè)連接來(lái)調(diào)用服務(wù)。連接以調(diào)用Context.bindService()方法建立,以調(diào)用 Context.unbindService()關(guān)閉。多個(gè)客戶(hù)端可以綁定至同一個(gè)服務(wù)。如果服務(wù)此時(shí)還沒(méi)有加載,bindService()會(huì)先加載它。

可被其他應(yīng)用程序復(fù)用,比如天氣預(yù)報(bào)服務(wù),其他應(yīng)用程序不需要再寫(xiě)這樣的服務(wù),調(diào)用已有的即可。

-----------------------------------------------------------------

1.  在同一個(gè)應(yīng)用任何地方調(diào)用 startService() 方法就能啟動(dòng) Service 了,然后系統(tǒng)會(huì)回調(diào) Service 類(lèi)的 onCreate() 以及 onStart() 方法。這樣啟動(dòng)的 Service 會(huì)一直運(yùn)行在后臺(tái),直到 Context.stopService() 或者 selfStop() 方法被調(diào)用。另外如果一個(gè) Service 已經(jīng)被啟動(dòng),其他代碼再試圖調(diào)用 startService() 方法,是不會(huì)執(zhí)行 onCreate() 的,但會(huì)重新執(zhí)行一次 onStart() 。

2. bindService()方法的意思是,把這個(gè)Service和調(diào)用Service的客戶(hù)類(lèi)綁起來(lái),如果調(diào)用這個(gè)客戶(hù)類(lèi)被銷(xiāo)毀,Service也會(huì)被銷(xiāo)毀。用這個(gè)方法的一個(gè)好處是,bindService()方法執(zhí)行后Service會(huì)回調(diào)onBind()方發(fā),它的作用是在Service和調(diào)用者之間建立一個(gè)橋梁,并不負(fù)責(zé)更多的工作,你可以從這里返回一個(gè)實(shí)現(xiàn)了IBind接口的類(lèi),在客戶(hù)端操作這個(gè)類(lèi)就能和這個(gè)服務(wù)通信了,比如得到Service運(yùn)行的狀態(tài)或其他操作。如果Service還沒(méi)有運(yùn)行,使用這個(gè)方法啟動(dòng)Service就會(huì)onCreate()方法而不會(huì)調(diào)用onStart()。一般使用bindService來(lái)綁定到一個(gè)現(xiàn)有的Service(即通過(guò)StartService啟動(dòng)的服務(wù))。

-----------------------------------------------------------------------

與Service通信并且讓它持續(xù)運(yùn)行

  如果我們想保持和Service的通信,又不想讓Service隨著Activity退出而退出呢?你可以先startService()然后再bindService()。當(dāng)你不需要綁定的時(shí)候就執(zhí)行unbindService()方法,執(zhí)行這個(gè)方法只會(huì)觸發(fā)Service的onUnbind()而不會(huì)把這個(gè)Service銷(xiāo)毀。這樣就可以既保持和Service的通信,也不會(huì)隨著Activity銷(xiāo)毀而銷(xiāo)毀了。

提高 Service 優(yōu)先級(jí)

  Android 系統(tǒng)對(duì)于內(nèi)存管理有自己的一套方法,為了保障系統(tǒng)有序穩(wěn)定的運(yùn)信,系統(tǒng)內(nèi)部會(huì)自動(dòng)分配,控制程序的內(nèi)存使用。當(dāng)系統(tǒng)覺(jué)得當(dāng)前的資源非常有限的時(shí)候,為了保證一些優(yōu)先級(jí)高的程序能運(yùn)行,就會(huì)殺掉一些他認(rèn)為不重要的程序或者服務(wù)來(lái)釋放內(nèi)存。這樣就能保證真正對(duì)用戶(hù)有用的程序仍然再運(yùn)行。如果你的 Service 碰上了這種情況,多半會(huì)先被殺掉。但如果你增加 Service 的優(yōu)先級(jí)就能讓他多留一會(huì),我們可以用setForeground(true) 來(lái)設(shè)置Service 的優(yōu)先級(jí)。

  為什么是 foreground ? 默認(rèn)啟動(dòng)的Service是被標(biāo)記為background,當(dāng)前運(yùn)行的Activity一般被標(biāo)記為foreground,也就是說(shuō)你給Service設(shè)置了foreground那么他就和正在運(yùn)行的Activity類(lèi)似優(yōu)先級(jí)得到了一定的提高。當(dāng)讓這并不能保證你得Service永遠(yuǎn)不被殺掉,只是提高了他的優(yōu)先級(jí)。

  優(yōu)先級(jí)規(guī)則

  1. 如果service正在調(diào)用onCreate,onStartCommand或者onDestory方法,那么用于當(dāng)前service的進(jìn)程則變?yōu)榍芭_(tái)進(jìn)程以避免被killed。

  2. 如果當(dāng)前service已經(jīng)被啟動(dòng)(start),擁有它的進(jìn)程則比那些用戶(hù)可見(jiàn)的進(jìn)程優(yōu)先級(jí)低一些,但是比那些不可見(jiàn)的進(jìn)程更重要,這就意味著service一般不會(huì)被killed.

  3. 如果客戶(hù)端已經(jīng)連接到service(bindService),那么擁有Service的進(jìn)程則擁有最高的優(yōu)先級(jí),可以認(rèn)為service是可見(jiàn)的。

  4. 如果service可以使用startForeground(int, Notification)方法來(lái)將service設(shè)置為前臺(tái)狀態(tài),那么系統(tǒng)就認(rèn)為是對(duì)用戶(hù)可見(jiàn)的,并不會(huì)在內(nèi)存不足時(shí)killed。

  如果有其他的應(yīng)用組件作為Service,Activity等運(yùn)行在相同的進(jìn)程中,那么將會(huì)增加該進(jìn)程的重要性。

-----------------------------------------------------------------------------------

Service生命周

Android Service生命周期與Activity生命周期是相似的,但是也存在一些細(xì)節(jié)上也存在著重要的不同:

onCreate和onStart是不同的

  通過(guò)從客戶(hù)端調(diào)用Context.startService(Intent)方法我們可以啟動(dòng)一個(gè)服務(wù)。如果這個(gè)服務(wù)還沒(méi)有運(yùn)行,Android將啟動(dòng)它并且在onCreate方法之后調(diào)用它的onStart方法。如果這個(gè)服務(wù)已經(jīng)在運(yùn)行,那么它的onStart方法將被新的Intent再次調(diào)用。所以對(duì)于單個(gè)運(yùn)行的Service它的onStart方法被反復(fù)調(diào)用是完全可能的并且是很正常的。

onResume、onPause以及onStop是不需要的

  回調(diào)一個(gè)服務(wù)通常是沒(méi)有用戶(hù)界面的,所以我們也就不需要onPause、onResume或者onStop方法了。無(wú)論何時(shí)一個(gè)運(yùn)行中的Service它總是在后臺(tái)運(yùn)行。

onBind

  如果一個(gè)客戶(hù)端需要持久的連接到一個(gè)服務(wù),那么他可以調(diào)用Context.bindService方法。如果這個(gè)服務(wù)沒(méi)有運(yùn)行,將通過(guò)調(diào)用onCreate方法去創(chuàng)建這個(gè)服務(wù)但并不調(diào)用onStart方法來(lái)啟動(dòng)它。相反,onBind方法將被客戶(hù)端的Intent調(diào)用,并且它返回一個(gè)IBind對(duì)象以便客戶(hù)端稍后可以調(diào)用這個(gè)服務(wù)。同一服務(wù)被客戶(hù)端同時(shí)啟動(dòng)和綁定是很正常的。

onDestroy

  與Activity一樣,當(dāng)一個(gè)服務(wù)被結(jié)束是onDestroy方法將會(huì)被調(diào)用。當(dāng)沒(méi)有客戶(hù)端啟動(dòng)或綁定到一個(gè)服務(wù)時(shí)Android將終結(jié)這個(gè)服務(wù)。與很多Activity時(shí)的情況一樣,當(dāng)內(nèi)存很低的時(shí)候Android也可能會(huì)終結(jié)一個(gè)服務(wù)。如果這種情況發(fā)生,Android也可能在內(nèi)存夠用的時(shí)候嘗試啟動(dòng)被終止的服務(wù),所以你的服務(wù)必須為重啟持久保存信息,并且最好在onStart方法內(nèi)來(lái)做。

使用context.startService() 啟動(dòng)Service是會(huì)會(huì)經(jīng)歷:

context.startService() ->onCreate()- >onStart()->Service running

context.stopService() | ->onDestroy() ->Service stop

  如果Service還沒(méi)有運(yùn)行,則android先調(diào)用onCreate()然后調(diào)用onStart();如果Service已經(jīng)運(yùn)行,則只調(diào)用onStart(),所以一個(gè)Service的onStart方法可能會(huì)重復(fù)調(diào)用多次。

  stopService的時(shí)候直接onDestroy,如果是調(diào)用者自己直接退出而沒(méi)有調(diào)用stopService的話(huà),Service會(huì)一直在后臺(tái)運(yùn)行。該Service的調(diào)用者再啟動(dòng)起來(lái)后可以通過(guò)stopService關(guān)閉Service。

所以調(diào)用startService的生命周期為:onCreate --> onStart(可多次調(diào)用) --> onDestroy

使用使用context.bindService()啟動(dòng)Service會(huì)經(jīng)歷:

context.bindService()->onCreate()->onBind()->Service running

onUnbind() -> onDestroy() ->Service stop

  onBind將返回給客戶(hù)端一個(gè)IBind接口實(shí)例,IBind允許客戶(hù)端回調(diào)服務(wù)的方法,比如得到Service運(yùn)行的狀態(tài)或其他操作。這個(gè)時(shí)候把調(diào)用者(Context,例如Activity)會(huì)和Service綁定在一起,Context退出了,Srevice就會(huì)調(diào)用onUnbind->onDestroy相應(yīng)退出。

所以調(diào)用bindService的生命周期為:onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory。

  在Service每一次的開(kāi)啟關(guān)閉過(guò)程中,只有onStart可被多次調(diào)用(通過(guò)多次startService調(diào)用),其他onCreate,onBind,onUnbind,onDestory在一個(gè)生命周期中只能被調(diào)用一次。

----------------------------------------

Service和Thread的區(qū)別

我們拿服務(wù)來(lái)進(jìn)行一個(gè)后臺(tái)長(zhǎng)時(shí)間的動(dòng)作,為了不阻塞線(xiàn)程,然而,Thread就可以達(dá)到這個(gè)效果,為什么我們不直接使用Thread去代替服務(wù)呢?(這個(gè)問(wèn)題摘抄至網(wǎng)上,原文地址不是是哪個(gè),所以沒(méi)寫(xiě)上)

這里提下,

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 線(xiàn)程上的。如:onCreate,onStart 這些函數(shù)在被系統(tǒng)調(diào)用的時(shí)候都是在主進(jìn)程的 main 線(xiàn)程上運(yùn)行的。如果是Remote Service,那么對(duì)應(yīng)的 Service 則是運(yùn)行在獨(dú)立進(jìn)程的 main 線(xiàn)程上。因此請(qǐng)不要把 Service 理解成線(xiàn)程,它跟線(xiàn)程半毛錢(qián)的關(guān)系都沒(méi)有!

既然這樣,那么我們?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í)行完畢的話(huà),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ù)器做某種同步的話(huà),該 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í)例)。

因此你可以把 Service 想象成一種消息服務(wù),而你可以在任何有 Context 的地方調(diào)用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,來(lái)控制它,你也可以在 Service 里注冊(cè) BroadcastReceiver,在其他地方通過(guò)發(fā)送 broadcast 來(lái)控制它,當(dāng)然這些都是 Thread 做不到的。

<manifest ... >

 ...

 <application ... >

   <service android:name=".ExampleService" />

   ...

 </application>

</manifest>

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線(xiàn),公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。

文章標(biāo)題:Service詳解-創(chuàng)新互聯(lián)
本文地址:http://www.muchs.cn/article32/dieppc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站營(yíng)銷(xiāo)、做網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)