2016-03-22 13:12:46 1404瀏覽
Service是不定時間運(yùn)行在后臺的一段代碼。是android 系統(tǒng)中的一種組件,它跟Activity的級別差不多,但是它不能自己運(yùn)行,需要通過某一個Activity或者其他Context對象來調(diào)用,只能后臺運(yùn)行。它可以運(yùn)行在它自己的進(jìn)程,也可以運(yùn)行在其他應(yīng)用程序進(jìn)程的上下文(context)里面。其它的組件可以綁定到一個服務(wù)(Service)上面,通過遠(yuǎn)程過程調(diào)用(RPC)來調(diào)用這個方法。例如媒體播放器的服務(wù),當(dāng)用戶退出媒體選擇用戶界面,仍然希望音樂依然可以繼續(xù)播放,這時就是由服務(wù) (service)來保證當(dāng)用戶界面關(guān)閉時音樂繼續(xù)播放的。
Service可以在和多場合的應(yīng)用中使用,比如播放多媒體的時候用戶啟動了其他Activity這個時候程序要在后臺繼續(xù)播放,比如檢測SD卡上文件的變化,再或者在后臺記錄你地理信息位置的改變等等,總之服務(wù)嘛,總是藏在后頭的。
每個Service必須在manifest中 通過來聲明。Service的啟動context.startService() 和 context.bindService()兩種方式。兩種啟動Service的方式有所不同。這里要說明一下的是如果在Service的onCreate或者onStart做一些很耗時間或者阻塞的操作,最好在Service里啟動一個子線程來完成,因為Service和其他的應(yīng)用組件一樣,是跑在主線程中,會影響到你的UI操作或者阻塞主線程中的其他事情。
1、本地服務(wù) (Local Servic)。用于應(yīng)用程序內(nèi)部,通過調(diào)用Context.startService()啟動,調(diào)用Context.stopService()結(jié)束,startService()可以傳遞參數(shù)給Service。
使用context.startService() 啟動Service會經(jīng)歷:
context.startService() ->onCreate()- >onStart()->Service running
context.stopService() | ->onDestroy() ->Service stop
如果Service還沒有運(yùn)行,則android先調(diào)用onCreate()然后調(diào)用onStart();如果Service已經(jīng)運(yùn)行,則只調(diào)用onStart(),所以一個Service的onStart方法可能會重復(fù)調(diào)用多次。 也就是說多次調(diào)用startService()方法并不會導(dǎo)致多次創(chuàng)建服務(wù),但會導(dǎo)致多次調(diào)用onStart()方法。
stopService的時候直接onDestroy,如果是調(diào)用者自己直接退出而沒有調(diào)用stopService的話,Service會一直在后臺運(yùn)行。該Service的調(diào)用者再啟動起來后可以通過stopService關(guān)閉Service。
所以調(diào)用startService的生命周期為:onCreate --> onStart(可多次調(diào)用) --> onDestroy
此方式主要用于實現(xiàn)應(yīng)用程序自己的一些耗時任務(wù),比如查詢升級信息,并不占用應(yīng)用程序比如Activity所屬線程,而是單開線程后臺執(zhí)行,這樣用戶體驗比較好。
2、遠(yuǎn)程服務(wù)(Remote Service)。用于Android開發(fā)系統(tǒng)內(nèi)部的應(yīng)用程序之間。它可以通過自己定義并暴露出來的接口進(jìn)行程序操作??蛻舳私⒁粋€到服務(wù)對象的連接,并通過那個連接來調(diào)用服務(wù)。連接以通過調(diào)用Context.bindService()啟動,調(diào)用Context.unbindservice()結(jié)束。多個客戶端可以綁定至同一個服務(wù)。
這種方式,可被其他應(yīng)用程序復(fù)用,比如天氣預(yù)報服務(wù),其他應(yīng)用程序不需要再寫這樣的服務(wù),調(diào)用已有的即可。
使用context.bindService()啟動Service會經(jīng)歷:
context.bindService()->onCreate()->onBind()->Service running
onUnbind() -> onDestroy() ->Service stop
onBind將返回給客戶端一個IBind接口實例,IBind允許客戶端回調(diào)Srevice的方法,比如得到Service運(yùn)行的狀態(tài)或其他操作。這個時候把調(diào)用者(Context,例如Activity)會和Service綁定在一起,Context退出了,Srevice就會調(diào)用onUnbind->onDestroy相應(yīng)退出。
所以調(diào)用bindService的生命周期為:onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory。
以上兩種方法都可以啟動Service,但是它們的使用場合有所不同。
使用startService()方法啟用服務(wù),調(diào)用者與服務(wù)之間沒有關(guān)聯(lián),即使調(diào)用者退出了,服務(wù)仍然運(yùn)行。
使用bindService()方法啟用服務(wù),調(diào)用者與服務(wù)綁定在了一起,調(diào)用者一旦退出,服務(wù)也就終止,大有“不求同時生,必須同時死”的特點(diǎn)。
onBind()只有采用Context.bindService()方法啟動服務(wù)時才會回調(diào)該方法。該方法在調(diào)用者與服務(wù)綁定時被調(diào)用,當(dāng)調(diào)用者與服務(wù)已經(jīng)綁定,多次調(diào)用Context.bindService()方法并不會導(dǎo)致該方法被多次調(diào)用。
兩種方式可以混合使用,比如說可以先startService再bindservice。
在Service每一次的開啟關(guān)閉過程中,只有onStart可被多次調(diào)用(通過多次startService調(diào)用),其他onCreate,onBind,onUnbind,onDestory在一個生命周期中只能被調(diào)用一次。
3、Service的生命周期。并不像Activity那么復(fù)雜,它只繼承了onCreate(),onStart(),onDestroy()三個方法,當(dāng)我們第一次啟動Service時,先后調(diào)用了onCreate(),onStart()這兩個方法,當(dāng)停止Service時,則執(zhí)行onDestroy()方法,這里需要注意的是,如果Service已經(jīng)啟動了,當(dāng)我們再次啟動Service時,不會在執(zhí)行onCreate()方法,而是直接執(zhí)行onStart()方法。
startService后,即使調(diào)用startService的進(jìn)程結(jié)束了,Service仍然還存在,直到有進(jìn)程調(diào)用stopService,或者Service自己自殺(Service.stopSelf()或者Service.stopSelfResult())。
bindService后,Service就和調(diào)用bindService的進(jìn)程同生共死了,也就是說當(dāng)調(diào)用bindService的進(jìn)程死了,那么它bind的Service也要跟著被結(jié)束,當(dāng)然期間也可以調(diào)用unbindservice讓 Service結(jié)束。
兩種方式混合使用時,比如說你startService了,我bindService了,那么只有你stopService了而且也unbindservice了,這個Service才會被結(jié)束。
4、擁有service的進(jìn)程具有較高的優(yōu)先級。Android系統(tǒng)將會盡量嘗試保留那些啟動了的或者是綁定了service的進(jìn)程。
如果該服務(wù)正在進(jìn)程的onCreate(), onStart(), 或者 onDestroy() 這些方法中執(zhí)行時, 那么主進(jìn)程將會成為一個前臺進(jìn)程,以確保此代碼不會被停止。
如果服務(wù)已經(jīng)開始,那么它的主進(jìn)程會就重要性而言低于所有可見的進(jìn)程但高于不可見的進(jìn)程, 由于只有少數(shù)幾個進(jìn)程是用戶可見的,所以只要不是內(nèi)存特別低,該服務(wù)不會停止.。
如果有多個客戶端綁定了服務(wù), 只要客戶端中的一個對于用戶是可見的,即認(rèn)為該服務(wù)可見。
如果service可以使用startForeground(int, Notification)方法來將service設(shè)置為前臺狀態(tài),那么系統(tǒng)就認(rèn)為是對用戶可見的,并不會在內(nèi)存不足時killed。
如果有其他的應(yīng)用組件作為Service,Activity等運(yùn)行在相同的進(jìn)程中,那么將會增加該進(jìn)程的重要性。
查看更多關(guān)于“Android培訓(xùn)資訊”的相關(guān)文章>>