前言
- 學(xué)
Android
有一段時間了旱函,想必不少人也和我一樣响巢,平時經(jīng)常東學(xué)西湊,感覺知識點有些凌亂難成體系棒妨。所以趁著這幾天忙里偷閑抵乓,把學(xué)的東西歸納下,捋捋思路。
這篇文章主要針對
Service
相關(guān)的知識點灾炭,進(jìn)行詳細(xì)的梳理,祝大家食用愉快颅眶!
文章目錄
方便大家學(xué)習(xí)蜈出,我在 GitHub 建立了 倉庫
倉庫內(nèi)容與博客同步更新。由于我在
稀土掘金
簡書
CSDN
博客園
等站點涛酗,都有新內(nèi)容發(fā)布铡原。所以大家可以直接關(guān)注該倉庫,以免錯過精彩內(nèi)容商叹!倉庫地址:
超級干貨燕刻!精心歸納Android
、JVM
剖笙、算法等卵洗,各位帥氣的老鐵支持一下!給個 Star 弥咪!
第一篇:Service 是什么
1.1 什么是 Service
-
Service
(服務(wù)) 是一個一種可以在后臺執(zhí)行長時間運行操作而沒有用戶界面的應(yīng)用組件过蹂。 - 服務(wù)可由其他應(yīng)用組件啟動(如
Activity
),服務(wù)一旦被啟動將在后臺一直運行聚至,即使啟動服務(wù)的組件(Activity
)已銷毀也不受影響酷勺。 - 此外,組件可以綁定到服務(wù)扳躬,以與之進(jìn)行交互脆诉,甚至是執(zhí)行進(jìn)程間通信 (
IPC
)。
1.2 Service 通炒遥總是稱之為 “后臺服務(wù)”
- 其中 “后臺” 一詞是相對于前臺而言的,具體是指:其本身的運行并不依賴于用戶可視的
UI
界面 - 因此片择,從實際業(yè)務(wù)需求上來理解潜的,
Service
的適用場景應(yīng)該具備以下條件:
并不依賴于用戶可視的
UI
界面(當(dāng)然,這一條其實也不是絕對的字管,如前臺Service
就是與Notification
界面結(jié)合使用的)具有較長時間的運行特性
注意: 是運行在主線程當(dāng)中的
1.3 服務(wù)進(jìn)程
服務(wù)進(jìn)程是通過
startService()
方法啟動的進(jìn)程啰挪,但不屬于前臺進(jìn)程和可見進(jìn)程。例如嘲叔,在后臺播放音樂或者在后臺下載就是服務(wù)進(jìn)程亡呵。系統(tǒng)保持它們運行,除非沒有足夠內(nèi)存來保證所有的前臺進(jìn)程和可視進(jìn)程硫戈。
第二篇:生命周期
2.1 Service 的生命周期
- 我們先來看看
Service
的生命周期 的基本流程 -
一張聞名遐邇的圖
2.2 開啟 Service 的兩種方式
2.2.1 startService()
定義一個類繼承
Service
在
Manifest.xml
文件中配置該Service
使用
Context
的startService(intent)
方法開啟服務(wù)锰什。使用
Context
的stopService(intent)
方法關(guān)閉服務(wù)。該啟動方式,
app
殺死汁胆、Activity
銷毀沒有任何影響梭姓,服務(wù)不會停止銷毀。
2.2.2 bindService()
創(chuàng)建
BindService
服務(wù)端嫩码,繼承Service
并在類中誉尖,創(chuàng)建一個實現(xiàn)IBinder
接口的實例對象,并提供公共方法給客戶端(Activity
)調(diào)用铸题。從
onBinder()
回調(diào)方法返回該Binder
實例铡恕。在客戶端(
Activity
)中, 從onServiceConnection()
回調(diào)方法參數(shù)中接收Binder
,通過Binder
對象即可訪問Service
內(nèi)部的數(shù)據(jù)丢间。在
manifests
中注冊BindService
, 在客戶端中調(diào)用bindService()
方法開啟綁定Service
, 調(diào)用unbindService()
方法注銷解綁Service
探熔。該啟動方式依賴于客戶端生命周期,當(dāng)客戶端
Activity
銷毀時, 沒有調(diào)用unbindService()
方法 ,Service
也會停止銷毀烘挫。
2.3 Service 有哪些啟動方法诀艰,有什么區(qū)別扶镀,怎樣停用 Service
- 在
Service
的生命周期中薇正,被回調(diào)的方法比Activity
少一些,只有onCreate
,onStartCommand
,onDestroy
,onBind
和onUnbind
宝与。
- 通常有兩種方式啟動一個
Service
, 他們對Service
生命周期的影響是不一樣的喜滨。
2.3.1 通過 startService
-
Service
會經(jīng)歷onCreate
到onStartCommand
捉捅,然后處于運行狀態(tài),stopService
的時候調(diào)用onDestroy
方法虽风。
如果是調(diào)用者自己直接退出而沒有調(diào)用
stopService
的話棒口,Service
會一直在后臺運行。
2.3.2 通過 bindService
Service
會運行 onCreate
辜膝,然后是調(diào)用 onBind
无牵, 這個時候調(diào)用者和 Service
綁定在一起。調(diào)用者退出了厂抖,Srevice
就會調(diào)用 onUnbind
-> onDestroyed
方法茎毁。
所謂綁定在一起就共存亡了。調(diào)用者也可以通過調(diào)用
unbindService
方法來停止服務(wù)忱辅,這時候Srevice
就會調(diào)用onUnbind
->onDestroyed
方法七蜘。
2.3.3 需要注意的是如果這幾個方法交織在一起的話,會出現(xiàn)什么情況呢墙懂?
一個原則是
Service
的onCreate
的方法只會被調(diào)用一次橡卤,就是你無論多少次的startService
又bindService
,Service
只被創(chuàng)建一次损搬。如果先是
bind
了碧库,那么start
的時候就直接運行Service
的onStartCommand
方法柜与,如果先是start
,那么bind
的時候就直接運行onBind
方法嵌灰。如果
service
運行期間調(diào)用了bindService
弄匕,這時候再調(diào)用stopService
的話,service
是不會調(diào)用onDestroy
方法的伞鲫,service
就stop
不掉了粘茄,只能調(diào)用UnbindService
,service
就會被銷毀如果一個
service
通過startService
被start
之后,多次調(diào)用startService
的話秕脓,service
會多次調(diào)
用onStartCommand
方法。多次調(diào)用stopService
的話儒搭,service
只會調(diào)用一次onDestroyed
方法吠架。如果一個
service
通過bindService
被start
之后,多次調(diào)用bindService
的話搂鲫,service
只會調(diào)用一次onBind
方法傍药。多次調(diào)用unbindService
的話會拋出異常。
第三篇:Service 與 Thread
3.1 Service 和 Thread 的區(qū)別
3.1.1 首先第一點定義上
-
thread
是程序執(zhí)行的最小單元魂仍,他是分配cpu
的基本單位安卓系統(tǒng)中拐辽,我們常說的主線程,UI
線程擦酌,也是線程的一種俱诸。當(dāng)然,線程里面還可以執(zhí)行一些耗時的異步操作赊舶。 - 而
service
大家記住睁搭,它是安卓中的一種特殊機(jī)制,service
是運行在主線程當(dāng)中的笼平,所以說它不能做耗時操作园骆,它是由系統(tǒng)進(jìn)程托管,其實service
也是一種輕量級的IPC
通信寓调,因為activity
可以和service
綁定锌唾,可以和service
進(jìn)行數(shù)據(jù)通信。 - 而且有一種情況夺英,
activity
和service
是處于不同的進(jìn)程當(dāng)中晌涕,所以說它們之間的數(shù)據(jù)通信,要通過IPC
進(jìn)程間通信的機(jī)制來進(jìn)行操作秋麸。
3.1.2 第二點是在實際開發(fā)的過程當(dāng)中
- 在安卓系統(tǒng)當(dāng)中渐排,線程一般指的是工作線程,就是后臺線程灸蟆,做一些耗時操作的線程驯耻,而主線程是一種特殊的線程亲族,它只是負(fù)責(zé)處理一些
UI
線程的繪制,UI
線程里面絕對不能做耗時操作可缚,這里是最基本最重要的一點霎迫。(這是Thread
在實際開發(fā)過程當(dāng)中的應(yīng)用) - 而
service
是安卓當(dāng)中,四大組件之一帘靡,一般情況下也是運行在主線程當(dāng)中知给,因此service
也是不可以做耗時操作的,否則系統(tǒng)會報 ANR 異常(ANR
全稱:Application Not Responding
)描姚,就是程序無法做出響應(yīng)涩赢。 - 如果一定要在
service
里面進(jìn)行耗時操作,一定要記得開啟單獨的線程去做轩勘。
3.1.3 第三點是應(yīng)用場景上
- 當(dāng)你需要執(zhí)行耗時的網(wǎng)絡(luò)筒扒,或者這種文件數(shù)據(jù)的查詢,以及其它阻塞
UI
線程的時候绊寻,都應(yīng)該使用工作線程花墩,也就是開啟一個子線程的方式。 - 這樣才能保證
UI
線程不被占用澄步,而影響用戶體驗冰蘑。 - 而
service
來說,我們經(jīng)常需要長時間在后臺運行村缸,而且不需要進(jìn)行交互的情況下才會使用到服務(wù)祠肥,比如說,我們在后臺播放音樂王凑,開啟天氣預(yù)報的統(tǒng)計搪柑,還有一些數(shù)據(jù)的統(tǒng)計等等。
3.2 為什么要用 Service 而不是 Thread
-
Thread
的運行是獨立于Activity
的索烹,也就是當(dāng)一個Activity
被finish
之后工碾,如果沒有主動停止Thread
或者Thread
中的run
沒有執(zhí)行完畢時那么這個線程會一直執(zhí)行下去。 - 因此這里會出現(xiàn)一個問題:當(dāng)
Activity
被finish
之后百姓,你不再持有該Thread
的引用渊额。 - 另一方面,你沒有辦法在不同的
Activity
中對同一Thread
進(jìn)行控制垒拢。
3.3 Service 里面是否能執(zhí)行耗時的操作
service 里面不能執(zhí)行耗時的操作(網(wǎng)絡(luò)請求,拷貝數(shù)據(jù)庫,大文件 )
Service
不是獨立的進(jìn)程旬迹,也不是獨立的線程,它是依賴于應(yīng)用程序的主線程的求类,也就是說奔垦,在更多時候不建議在Service
中編寫耗時的邏輯和操作(比如:網(wǎng)絡(luò)請求,拷貝數(shù)據(jù)庫尸疆,大文件)椿猎,否則會引起ANR
惶岭。如果想在服務(wù)中執(zhí)行耗時的任務(wù)。有以下解決方案:
- 在
service
中開啟一個子線程
new Thread(){}.start();
- 可以使用
IntentService
異步管理服務(wù)( 有關(guān)IntentService
的內(nèi)容在后文中給出 )
3.4 Service 是否在 main thread 中執(zhí)行
- 默認(rèn)情況, 如果沒有顯示的指
service
所運行的進(jìn)程,Service
和activity
是運 行在當(dāng)前app
所在進(jìn)程的main thread
(UI
主線程)里面犯眠。 -
Service
和Activity
在同一個線程按灶,對于同一app
來說默認(rèn)情況下是在同一個線程中的main Thread
(UI Thread
) - 特殊情況 ,可以在清單文件配置
service
執(zhí)行所在的進(jìn)程 ,讓service
在另 外的進(jìn)程中執(zhí)行Service
不死之身
3.4.1 在 onStartCommand
方法中將 flag
設(shè)置為 START_STICKY
;
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" >
</service>
return Service.START_STICKY;
3.4.2 在 xml 中設(shè)置了 android:priority
<!--設(shè)置服務(wù)的優(yōu)先級為MAX_VALUE-->
<service android:name=".MyService"
android:priority="2147483647"
>
</service>
3.4.3 在 onStartCommand
方法中設(shè)置為前臺進(jìn)程
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Notification notification = new Notification(R.mipmap.ic_launcher, "服務(wù)正在運行",System.currentTimeMillis());
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,notificationIntent,0);
RemoteViews remoteView = new RemoteViews(this.getPackageName(),R.layout.notification);
remoteView.setImageViewResource(R.id.image, R.mipmap.ic_launcher);
remoteView.setTextViewText(R.id.text , "Hello,this message is in a custom expanded view");
notification.contentView = remoteView;
notification.contentIntent = pendingIntent;
startForeground(1, notification);
return Service.START_STICKY;
}
3.4.4 在 onDestroy
方法中重啟 service
@Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, MyService.class));
}
3.4.5 用 AlarmManager.setRepeating(…)
方法循環(huán)發(fā)送鬧鐘廣播, 接收的時候調(diào)用 service
的 onStartCommand
方法
Intent intent = new Intent(MainActivity.this,MyAlarmReciver.class);
PendingIntent sender = PendingIntent.getBroadcast( MainActivity.this, 0, intent, 0);
// We want the alarm to go off 10 seconds from now.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 1);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
//重復(fù)鬧鐘
/**
* @param type
* @param triggerAtMillis t 鬧鐘的第一次執(zhí)行時間,以毫秒為單位
* go off, using the appropriate clock (depending on the alarm type).
* @param intervalMillis 表示兩次鬧鐘執(zhí)行的間隔時間筐咧,也是以毫秒為單位
* of the alarm.
* @param operation 綁定了鬧鐘的執(zhí)行動作鸯旁,比如發(fā)送一個廣播、給出提示等等
*/
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 2 * 1000, sender);
3.4.6 目前市場面的很多三方的消息推送 SDK
喚醒 APP
, 例如 Jpush
PS
: 以上這些方法并不代表著你的Service
就永生不死了量蕊,只能說是提高了進(jìn)程的優(yōu)先級铺罢。迄今為止我沒有發(fā)現(xiàn)能夠通過常規(guī)方法達(dá)到流氓需求 (通過長按home
鍵清除都清除不掉) 的方法,目前所有方法都是指通過Android
的內(nèi)存回收機(jī)制和普通的第三方內(nèi)存清除等手段后仍然保持運行的方法残炮,有些手機(jī)廠商把這些知名的app
放入了自己的白名單中畏铆,保證了進(jìn)程不死來提高用戶體驗(如微信、app
一樣躲避不了被殺的命運蛋勺。
第四篇:InterService
- 作為一個老司機(jī),如果連
Interservice
都沒聽說過鸠删,那就有點那個啥了
4.1 什么是 IntentService
IntentService
是Service
的子類抱完,比普通的Service
增加了額外的功能。我們常用的
Service
存在兩個問題:
Service
不會專門啟動一條單獨的進(jìn)程刃泡,Service
與它所在應(yīng)用位于同一個進(jìn)程中Service
也不是專門一條新線程巧娱,因此不應(yīng)該在Service
中直接處理耗時的任務(wù)
4.2 IntentService 的特征
會創(chuàng)建獨立的
worker
線程來處理所有的Intent
請求會創(chuàng)建獨立的
worker
線程來處理onHandleIntent()
方法實現(xiàn)的代碼,無需處理多線程問題所有請求處理完成后烘贴,
IntentService
會自動停止禁添,無需調(diào)用stopSelf()
方法停止Service
為
Service
的onBind()
提供默認(rèn)實現(xiàn),返回null
為
Service
的onStartCommand
提供默認(rèn)實現(xiàn)桨踪,將請求Intent
添加到隊列中
4.3 Service 和 IntentService 區(qū)別
4.3.1 Service
是用于后臺服務(wù)的
- 當(dāng)應(yīng)用程序被掛到后臺的時候老翘,為了保證應(yīng)用某些組件仍然可以工作而引入了
Service
這個概念 - 那么這里面要強(qiáng)調(diào)的是:
Service
不是獨立的進(jìn)程,也不是獨立的線程锻离,它是依賴于應(yīng)用程序的主線程的铺峭,也就是說,在更多時候不建議在Service
中編寫耗時的邏輯和操作汽纠,否則會引起ANR
卫键。
也就是,service 里面不可以進(jìn)行耗時的操作虱朵。雖然在后臺服務(wù)莉炉。但是也是在主線程里面钓账。
4.3.2 當(dāng)我們編寫的耗時邏輯,不得不被 service
來管理的時候呢袱,就需要引入 IntentService
官扣。
-
IntentService
是繼承Service
的,那么它包含了Service
的全部特性羞福,當(dāng)然也包含service
的生命周期惕蹄。 - 那么與
service
不同的是,IntentService
在執(zhí)行onCreate
操作的時候治专,內(nèi)部開了一個線程卖陵,去你執(zhí)行你的耗時操作。
4.3.3 使用:
- 重寫
protected abstract void onHandleIntent(Intent intent)
4.3.4 IntentService
是一個通過 Context.startService(Intent)
啟動可以處理異步請求的 Service
- 使用時你只需要繼承
IntentService
和重寫其中的onHandleIntent(Intent)
方法接收一個Intent
對象 , 在適當(dāng)?shù)臅r候會停止自己 ( 一般在工作完成的時候 ) 张峰。 - 所有的請求的處理都在一個工作線程中完成 , 它們會交替執(zhí)行 ( 但不會阻塞主線程的執(zhí)行 ) 泪蔫,一次只能執(zhí)行一個請求。
4.3.5 是一個基于消息的服務(wù)
- 每次啟動該服務(wù)并不是馬上處理你的工作喘批,而是首先會創(chuàng)建對應(yīng)的
Looper
撩荣,Handler
并且在MessageQueue
中添加的附帶客戶Intent
的Message
對象。 - 當(dāng)
Looper
發(fā)現(xiàn)有Message
的時候接著得到Intent
對象通過在onHandleIntent((Intent)msg.obj)
中調(diào)用你的處理程序饶深,處理完后即會停止自己的服務(wù)餐曹。 - 意思是
Intent
的生命周期跟你的處理的任務(wù)是一致的,所以這個類用下載任務(wù)中非常好敌厘,下載任務(wù)結(jié)束后服務(wù)自身就會結(jié)束退出台猴。
4.3.6 總結(jié) IntentService
的特征有:
會創(chuàng)建獨立的
worker
線程來處理所有的Intent
請求;會創(chuàng)建獨立的
worker
線程來處理onHandleIntent()
方法實現(xiàn)的代碼俱两,無需處理多線程問題饱狂;所有請求處理完成后,
IntentService
會自動停止宪彩,無需調(diào)用stopSelf()
方法停止Service
休讳;
第五篇:Service 與 Activity
5.1 Activity 怎么和 Service 綁定,怎么在 Activity 中啟動對應(yīng)的 Service
Activity
通過bindService(Intent service, ServiceConnection conn, int flags)
跟Service
進(jìn)行綁定毯焕,當(dāng)綁定成功的時候Service
會將代理對象通過回調(diào)的形式傳給conn
衍腥,這樣我們就拿到了Service
提供的服務(wù)代理對象。在
Activity
中可以通過startService
和bindService
方法啟動Service
纳猫。一般情況下如果想獲取Service
的服務(wù)對象那么肯定需要通過bindService()
方法婆咸,比如音樂播放器,第三方支付等芜辕。如果僅僅只是為了開啟一個后臺任務(wù)那么可以使用
startService()
方法尚骄。
5.2 說說 Activity 、Intent 侵续、Service 是什么關(guān)系
他們都是
Android
開發(fā)中使用頻率最高的類。其中Activity
和Service
都屬于Android
的四大組件需五。他倆都是Context
類的子類ContextWrapper
的子類鹉动,因此他倆可以算是兄弟關(guān)系吧。不過他們各有各自的本領(lǐng)宏邮,
Activity
負(fù)責(zé)用戶界面的顯示和交互泽示,Service
負(fù)責(zé)后臺任務(wù)的處理。Activity
和Service
之間可以通過Intent
傳遞數(shù)據(jù)蜜氨,因此可以把Intent
看作是通信使者械筛。
5.3 Service 和 Activity 在同一個線程嗎
對于同一 app
來說默認(rèn)情況下是在同一個線程中的,main Thread
( UI Thread
)飒炎。
5.4 Service 里面可以彈吐司么
- 可以
- 彈吐司有個條件是:得有一個
Context
上下文埋哟,而Service
本身就是Context
的子類 - 因此在
Service
里面彈吐司是完全可以的谜诫。比如我們在Service
中完成下載任務(wù)后可以彈一個吐司通知給用戶罚勾。
5.5 與 Service 交互方式
5.5.1 廣播交互
-
Server
端將目前的下載進(jìn)度,通過廣播的方式發(fā)送出來渊涝,Client
端注冊此廣播的監(jiān)聽器煞赢,當(dāng)獲取到該廣播后砍鸠,將廣播中當(dāng)前的下載進(jìn)度解析出來并更新到界面上。 - 定義自己的廣播耕驰,這樣在不同的
Activity
、Service
以及應(yīng)用程序之間录豺,就可以通過廣播來實現(xiàn)交互朦肘。
5.5.2 共享文件交互
- 我們使用
SharedPreferences
來實現(xiàn)共享,當(dāng)然也可以使用其它IO
方法實現(xiàn)双饥,通過這種方式實現(xiàn)交互時需要注意媒抠,對于文件的讀寫的時候,同一時間只能一方讀一方寫咏花,不能兩方同時寫趴生。 -
Server
端將當(dāng)前下載進(jìn)度寫入共享文件中,Client
端通過讀取共享文件中的下載進(jìn)度昏翰,并更新到主界面上苍匆。
5.5.3 Messenger
交互 ( 信使交互 )
-
Messenger
翻譯過來指的是信使,它引用了一個Handler
對象棚菊,別人能夠向它發(fā)送消息 ( 使用mMessenger.send ( Message msg )
方法)浸踩。 - 該類允許跨進(jìn)程間基于
Message
通信,在服務(wù)端使用Handler
創(chuàng)建一個Messenger
统求,客戶端只要獲得這個服務(wù)端的Messenger
對象就可以與服務(wù)端通信了 - 在
Server
端與 Client 端之間通過一個Messenger
對象來傳遞消息检碗,該對象類似于信息中轉(zhuǎn)站据块,所有信息通過該對象攜帶
5.5.4 自定義接口交互
- 其實就是我們自己通過接口的實現(xiàn)來達(dá)到
Activity
與Service
交互的目的,我們通過在Activity
和Service
之間架設(shè)一座橋樑折剃,從而達(dá)到數(shù)據(jù)交互的目的另假,而這種實現(xiàn)方式和AIDL
非常類似 - 自定義一個接口,該接口中有一個獲取當(dāng)前下載進(jìn)度的空方法怕犁。
Server
端用一個類繼承自Binder
并實現(xiàn)該接口边篮,覆寫了其中獲取當(dāng)前下載進(jìn)度的方法。Client
端通過ServiceConnection
獲取到該類的對象因苹,從而能夠使用該獲取當(dāng)前下載進(jìn)度的方法苟耻,最終實現(xiàn)實時交互。
5.5.5 AIDL
交互
- 遠(yuǎn)程服務(wù)一般通過
AIDL
來實現(xiàn)扶檐,可以進(jìn)行進(jìn)程間通信凶杖,這種服務(wù)也就是遠(yuǎn)程服務(wù)。 -
AIDL
屬于Android
的IPC
機(jī)制款筑,常用于跨進(jìn)程通信智蝠,主要實現(xiàn)原理基于底層Binder
機(jī)制。
第六篇:使用
6.1 什么情況下會使用 Service
6.1.1 經(jīng)驗總結(jié):
-
Service
其實就是背地搞事情杈湾,又不想讓別人知道 - 舉一個生活當(dāng)中的例子,你想知道一件事情不需要直接去問攘须,你可以通過側(cè)面了解漆撞。這就是
Service
設(shè)計的初衷
6.1.2 Service
為什么被設(shè)計出來
- 根據(jù)
Service
的定義,我們可以知道需要長期在后臺進(jìn)行的工作我們需要將其放在Service
中去做于宙。 - 得再通熟易懂一點浮驳,就是不能放在
Activity
中來執(zhí)行的工作就必須得放到Service
中去做。 - 如:音樂播放捞魁、下載至会、上傳大文件、定時關(guān)閉應(yīng)用等功能谱俭。這些功能如果放到
Activity
中做的話奉件,那么Activity
退出被銷毀了的話,那這些功能也就停止了昆著,這顯然是不符合我們的設(shè)計要求的县貌,所以要將他們放在Service
中去執(zhí)行。
6.2 onStartCommand() 返回值 int 值的區(qū)別
- 有四種返回值,不同值代表的意思如下:
6.2.1 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
。
6.2.2 START_NOT_STICKY
:
- “非粘性的”。
- 使用這個返回值時 , 如果在執(zhí)行完
onStartCommand
后 , 服務(wù)被異常kill
掉 杭攻,系統(tǒng)不會自動重啟該服務(wù)祟敛。
6.2.3 START_REDELIVER_INTENT
:
- 重傳
Intent
。 - 使用這個返回值時,如果在執(zhí)行完
onStartCommand
后,服務(wù)被異常 kill 掉 - 系統(tǒng)會自動重啟該服務(wù) , 并將 Intent 的值傳入兆解。
6.2.4 START_STICKY_COMPATIBILITY
:
-
START_STICKY
的兼容版本 , 但不保證服務(wù)被kill
后一定能重啟馆铁。
6.3 在 service 的生命周期方法 onstartConmand() 可不可以執(zhí)行網(wǎng)絡(luò)操作?如何在 service 中執(zhí)行網(wǎng)絡(luò)操作锅睛?
- 可以直接在
Service
中執(zhí)行網(wǎng)絡(luò)操作 - 在
onStartCommand()
方法中可以執(zhí)行網(wǎng)絡(luò)操作
6.4 提高 service 的優(yōu)先級
在
AndroidManifest.xml
文件中對于intent-filter
可以通過android:priority = “1000”
這個屬性設(shè)置最高優(yōu)先級现拒,1000
是最高值辣垒,如果數(shù)字越小則優(yōu)先級越低,同時實用于廣播印蔬。在
onStartCommand
里面調(diào)用startForeground()
方法把Service
提升為前臺進(jìn)程級別勋桶,然后再onDestroy
里面要記得調(diào)用stopForeground ()
方法。onStartCommand
方法侥猬,手動返回START_STICKY
例驹。
- 在
onDestroy
方法里發(fā)廣播重啟service
。
-
service
+broadcast
方式退唠,就是當(dāng)service
走ondestory
的時候鹃锈,發(fā)送一個自定義的廣播 - 當(dāng)收到廣播的時候,重新啟動
service
瞧预。( 第三方應(yīng)用或是在setting
里-應(yīng)用強(qiáng)制停止時屎债,APP
進(jìn)程就直接被干掉了,onDestroy
方法都進(jìn)不來垢油,所以無法保證會執(zhí)行 )
- 監(jiān)聽系統(tǒng)廣播判斷
Service
狀態(tài)扔茅。
- 通過系統(tǒng)的一些廣播
- 比如:手機(jī)重啟、界面喚醒秸苗、應(yīng)用狀態(tài)改變等等監(jiān)聽并捕獲到,然后判斷我們的
Service
是否還存活运褪。
-
Application
加上Persistent
屬性惊楼。
6.5 Service 的 onRebind ( Intent ) 方法在什么情況下會執(zhí)行
- 如果在
onUnbind()
方法返回true
的情況下會執(zhí)行 , 否則不執(zhí)行。
總結(jié)
- 本文基本涵蓋了
Android Service
相關(guān)的知識點秸讹。由于篇幅原因檀咙,諸如 InterService 具體使用方法等,沒辦法詳細(xì)的介紹璃诀,大家很容易就能在網(wǎng)上找到資料進(jìn)行學(xué)習(xí)弧可。 -
重點
:關(guān)于Android
的四大組件,到現(xiàn)在為止我才總結(jié)完Activity
和Service
劣欢,我將繼續(xù)針對棕诵,BroadcastRecevier
ContentProvider
等裁良,以及四大組件之外的,事件分發(fā)校套、滑動沖突价脾、新能優(yōu)化等重要模塊,進(jìn)行全面總結(jié)笛匙,歡迎大家關(guān)注 _yuanhao 的 簡書侨把,方便及時接收更新 - 開始前還以為總結(jié)不難,實際寫文章的過程中妹孙,才知道什么是艱辛秋柄。也不知道自己能不能咬牙堅持下去,希望大家給我鼓勵蠢正,就算只是一個贊骇笔,也是我堅持下去的理由!
碼字不易机隙,你的點贊是我總結(jié)的最大動力蜘拉!
由于我在「稀土掘金」「簡書」「
CSDN
」「博客園」等站點,都有新內(nèi)容發(fā)布有鹿。所以大家可以直接關(guān)注我的GitHub
倉庫旭旭,以免錯過精彩內(nèi)容!倉庫地址:
超級干貨葱跋!精心歸納Android
持寄、JVM
、算法等娱俺,各位帥氣的老鐵支持一下稍味!給個 Star !1W
多字長文荠卷,加上精美思維導(dǎo)圖模庐,記得點贊哦,歡迎關(guān)注 _yuanhao 的 簡書相關(guān)文章均可在我的主頁油宜、GitHub 上看到掂碱,這里限于篇幅原因,也為了保持界面整潔慎冤,讓大家能有跟舒心的閱讀體驗就不給出了疼燥,我們下篇文章不見不散!