1、啟動方式和區(qū)別
startService
其他組件調(diào)用startService()
啟動一個Service劫乱。一旦啟動织中,Service將一直在后臺運(yùn)行,即時(shí)啟動這個Service的組件被銷毀衷戈。通常startService會在后臺執(zhí)行單獨(dú)的操作狭吼,并不需要和啟動它的組件交互。只有當(dāng)Service自己調(diào)用stopSelf()
或者其他組件調(diào)用stopService()
才會終止殖妇。bindService
其他組件還可以通過bindService()
的方法來綁定一個Service刁笙。可以通過調(diào)用Service內(nèi)部方法,也可以提供組件與Service交互的接口采盒,進(jìn)行擴(kuò)進(jìn)程通信(IPC)旧乞。這種方式會讓Service和啟動它的組件綁定一起,當(dāng)啟動它的組件被銷毀磅氨,Service也會自動進(jìn)行unBind操作尺栖。同時(shí)一個Service可以被多個組件綁定,只有所有綁定它的組件都進(jìn)行了unBind()
操作烦租,這個Service才會被銷毀混合啟動模式
當(dāng)播放音樂的時(shí)候延赌,需要調(diào)用startService()
啟動指定的音樂,又需要獲取該音樂的播放進(jìn)度的時(shí)候叉橱,又需要調(diào)用bindService()
挫以。該方式保證了Service可長期在后臺運(yùn)行,還可讓調(diào)用者遠(yuǎn)程調(diào)用Service中提供的方法窃祝。在這種情況下掐松,除非Service被unBind,在此之前stopService()
和stopSelf()
都不能停止該服務(wù)
Service不同的啟動方式有不同的生命周期與回調(diào)方法粪小,
startService()
啟動Service會回調(diào)onStartCommand()
大磺,bindService()
綁定Service會回調(diào)onBind()
。
無論哪種方式啟動Service探膊,任何組件都可以使用Service(甚至其他的應(yīng)用程序的組件)杠愧,并通過Intent傳遞參數(shù)。你可以在
AndroidMenifest.xml
中將android:exported="false"
Service配置成私有的逞壁,不允許其他應(yīng)用訪問流济。這樣配置不允許其他應(yīng)用程序啟動本應(yīng)用的Service,即便是顯示的Intent也不行腌闯。
2绳瘟、生命周期
這個基本上初級程序員都會學(xué)習(xí)到的,就不述說了姿骏。來說說重點(diǎn)吧稽荧!
- 完整生命周期:從
onCreate()
到onDestroy()
返回。和Activity類似工腋,一般在onCreate()
方法中做一些初始化的工作,在onDestroy()方法中做一些資源釋放的工作畅卓。如若Service在后臺播放一個音樂擅腰,就需要在onCreate()
方法中開啟一個線程啟動音樂,并在onDestroy()
中結(jié)束線程翁潘。- 活動生命周期:從
onStartCommand()
或onBind()
回調(diào)開始趁冈,由相應(yīng)的startService()
或bindService()
調(diào)用。start 方式的活動生命周期結(jié)束就意味著完整證明周期的結(jié)束,而 bind 方式渗勘,當(dāng)onUnbind()
返回后沐绒,Service 的活動生命周期結(jié)束。
注意
- 無論是
startService()
還是bindService()
啟動Service旺坠,onCreate()
和onDestroy()
均會被調(diào)用且只會被執(zhí)行一次乔遮。onStartCommand()
可以執(zhí)行多次,也就是說一旦Service創(chuàng)建過了取刃,而又沒有被銷毀的話蹋肮, 不管是再次調(diào)用bindService還是startService都不會再走onCreate()
,onBind()
也只會執(zhí)行一次璧疗,多次調(diào)用startService會多次執(zhí)行onStartCommand()
- Service中的
onBind()
方法返回null的話坯辩,無法回調(diào)ServiceConnection
3、AndroidManifest里Service的常見屬性說明
屬性 | 說明 | 備注 |
---|---|---|
android:name | 類名 | |
android:enabled | 系統(tǒng)默認(rèn)啟動 | 不設(shè)置則默認(rèn)為false默認(rèn)為true崩侠,被系統(tǒng)啟動漆魔。適用于四大組件 |
android:label | 名字 | 若不設(shè)置,默認(rèn)為Service類名 |
android:icon | 圖標(biāo) | |
android:permission | 申請此Service的權(quán)限 | 有提供了該權(quán)限的應(yīng)用才能控制或連接此服務(wù) |
android:process | 是否在另一個進(jìn)程中運(yùn)行(遠(yuǎn)程服務(wù)) | 不設(shè)置默認(rèn)為本地服務(wù)却音,remote則設(shè)置成遠(yuǎn)程服務(wù) |
android:exported | 是否能夠被其他應(yīng)用程序所控制或連接 | 不設(shè)置默認(rèn)為false |
4改抡、如何提高service的優(yōu)先級
1、在AndroidManifest.xml文件中對于intent-filter可以通過android:priority = “1000”這個屬性設(shè)置最高優(yōu)先級僧家,1000是最高值雀摘,如果數(shù)字越小則優(yōu)先級越低,同時(shí)實(shí)用于廣播八拱。
2阵赠、在onStartCommand里面調(diào)用 startForeground()方法把Service提升為前臺進(jìn)程級別,然后再onDestroy里面要記得調(diào)用stopForeground ()方法肌稻。
3清蚀、onStartCommand方法,手動返回START_STICKY爹谭。
4枷邪、 在onDestroy方法里發(fā)廣播重啟service。
service +broadcast 方式诺凡,就是當(dāng)service走ondestory的時(shí)候东揣,發(fā)送一個自定義的廣播,當(dāng)收到廣播的時(shí)候腹泌,重新啟動service嘶卧。(第三方應(yīng)用或是在setting里-應(yīng)用-強(qiáng)制停止時(shí),APP進(jìn)程就直接被干掉了凉袱,onDestroy方法都進(jìn)不來芥吟,所以無法保證會執(zhí)行)
5侦铜、監(jiān)聽系統(tǒng)廣播判斷Service狀態(tài)。
通過系統(tǒng)的一些廣播钟鸵,比如:手機(jī)重啟钉稍、界面喚醒、應(yīng)用狀態(tài)改變等等監(jiān)聽并捕獲到棺耍,然后判斷我們的Service是否還存活贡未。
6、Application加上Persistent屬性烈掠。
5羞秤、Service的onStartCommand()方法有幾種返回值?
-
START_STICKY: 如果 service 進(jìn)程被 kill 掉,保留 service 的狀態(tài)為開始狀態(tài),但不保留遞送的 intent 對象左敌。隨 后系統(tǒng)會嘗試重新創(chuàng)建 service,由于服務(wù)狀態(tài)為開始狀態(tài),所以創(chuàng)建服務(wù)后一定會調(diào)用
onStartCommand(Intent,int,int)
方法瘾蛋。如果在此期間沒有任何啟動命令被傳遞到 service,那么參數(shù) Intent 將為 null。 -
START_NOT_STICKY: 非粘性的”矫限。使用這個返回值時(shí),如果在執(zhí)行完
onStartCommand()
后,服務(wù)被異常 kill 掉,系統(tǒng)不會自動重啟該服務(wù)哺哼。 -
START_REDELIVER_INTENT: 重傳 Intent。使用這個返回值時(shí),如果在執(zhí)行完
onStartCommand()
后,服務(wù)被異 常 kill 掉,系統(tǒng)會自動重啟該服務(wù),并將 Intent 的值傳入叼风。 - START_STICKY_COMPATIBILITY: START_STICKY 的兼容版本,但不保證服務(wù)被 kill 后一定能重啟取董。
6、Service的onRebind(Intent)方法什么時(shí)候會執(zhí)行无宿?
如果在 onUnbind()
返回true的情況下會執(zhí)行茵汰,否則不執(zhí)行。
調(diào)用過程:
1孽鸡、啟動服務(wù) onCreate()
蹂午,onStartCommand()
方法被回調(diào);
2彬碱、綁定服務(wù) onBind()
方法被回調(diào)豆胸;
3、 解綁服務(wù)(可以調(diào)用 unBindService()
方法巷疼,或退出綁定Service的Activity組件) onUnbind()
方法被回調(diào)晚胡;
4,重新綁定服務(wù) (eg:再次進(jìn)入該Activity嚼沿,調(diào)用bindService方法綁定服務(wù)) onRebind(Intent)
方法被回調(diào)估盘。
7、你一般在什么情況下會使用Service骡尽?
經(jīng)驗(yàn)總結(jié):
Service其實(shí)就是背地搞事情忿檩,又不想讓別人知道,舉一個生活當(dāng)中的例子爆阶,你想知道一件事情不需要直接去問,你可以通過側(cè)面了解。這就是Service設(shè)計(jì)的初衷Service為什么被設(shè)計(jì)出來辨图?
根據(jù)Service的定義班套,我們可以知道需要長期在后臺進(jìn)行的工作我們需要將其放在Service中去做。說得再通熟易懂一點(diǎn)故河,就是不能放在Activity中來執(zhí)行的工作就必須得放到Service中去做吱韭。如:音樂播放、下載鱼的、上傳大文件理盆、定時(shí)關(guān)閉應(yīng)用等功能。這些功能如果放到Activity中做的話凑阶,那Activity退出被銷毀了的話猿规,那這些功能也就停止了,這顯然是不符合我們的設(shè)計(jì)要求的宙橱,所以要將他們放在Service中去執(zhí)行姨俩。