前言
- 學(xué)
Android有一段時(shí)間了,想必不少人也和我一樣,平時(shí)經(jīng)常東學(xué)西湊,感覺知識(shí)點(diǎn)有些凌亂難成體系。所以趁著這幾天忙里偷閑,把學(xué)的東西歸納下,捋捋思路。
這篇文章主要針對
Service相關(guān)的知識(shí)點(diǎn),進(jìn)行詳細(xì)的梳理,祝大家食用愉快!
文章目錄

方便大家學(xué)習(xí),我在 GitHub 建立了 倉庫
倉庫內(nèi)容與博客同步更新。由于我在
稀土掘金簡書CSDN博客園等站點(diǎn),都有新內(nèi)容發(fā)布。所以大家可以直接關(guān)注該倉庫,以免錯(cuò)過精彩內(nèi)容!
第一篇:Service 是什么

1.1 什么是 Service

-
Service(服務(wù)) 是一個(gè)一種可以在后臺(tái)執(zhí)行長時(shí)間運(yùn)行操作而沒有用戶界面的應(yīng)用組件。 - 服務(wù)可由其他應(yīng)用組件啟動(dòng)(如
Activity),服務(wù)一旦被啟動(dòng)將在后臺(tái)一直運(yùn)行,即使啟動(dòng)服務(wù)的組件(Activity)已銷毀也不受影響。 - 此外,組件可以綁定到服務(wù),以與之進(jìn)行交互,甚至是執(zhí)行進(jìn)程間通信 (
IPC)。
1.2 Service 通??偸欠Q之為 “后臺(tái)服務(wù)”

- 其中 “后臺(tái)” 一詞是相對于前臺(tái)而言的,具體是指:其本身的運(yùn)行并不依賴于用戶可視的
UI界面 - 因此,從實(shí)際業(yè)務(wù)需求上來理解,
Service的適用場景應(yīng)該具備以下條件:
并不依賴于用戶可視的
UI界面(當(dāng)然,這一條其實(shí)也不是絕對的,如前臺(tái)Service就是與Notification界面結(jié)合使用的)具有較長時(shí)間的運(yùn)行特性
注意: 是運(yùn)行在主線程當(dāng)中的
1.3 服務(wù)進(jìn)程

服務(wù)進(jìn)程是通過
startService()方法啟動(dòng)的進(jìn)程,但不屬于前臺(tái)進(jìn)程和可見進(jìn)程。例如,在后臺(tái)播放音樂或者在后臺(tái)下載就是服務(wù)進(jìn)程。系統(tǒng)保持它們運(yùn)行,除非沒有足夠內(nèi)存來保證所有的前臺(tái)進(jìn)程和可視進(jìn)程。
第二篇:生命周期

2.1 Service 的生命周期
- 我們先來看看
Service的生命周期 的基本流程 -
一張聞名遐邇的圖
Service的生命周期
2.2 開啟 Service 的兩種方式

2.2.1 startService()

定義一個(gè)類繼承
Service在
Manifest.xml文件中配置該Service使用
Context的startService(intent)方法開啟服務(wù)。使用
Context的stopService(intent)方法關(guān)閉服務(wù)。該啟動(dòng)方式,
app殺死、Activity銷毀沒有任何影響,服務(wù)不會(huì)停止銷毀。
2.2.2 bindService()

創(chuàng)建
BindService服務(wù)端,繼承Service并在類中,創(chuàng)建一個(gè)實(shí)現(xiàn)IBinder接口的實(shí)例對象,并提供公共方法給客戶端(Activity)調(diào)用。從
onBinder()回調(diào)方法返回該Binder實(shí)例。在客戶端(
Activity)中, 從onServiceConnection()回調(diào)方法參數(shù)中接收Binder,通過Binder對象即可訪問Service內(nèi)部的數(shù)據(jù)。在
manifests中注冊BindService, 在客戶端中調(diào)用bindService()方法開啟綁定Service, 調(diào)用unbindService()方法注銷解綁Service。該啟動(dòng)方式依賴于客戶端生命周期,當(dāng)客戶端
Activity銷毀時(shí), 沒有調(diào)用unbindService()方法 ,Service也會(huì)停止銷毀。
2.3 Service 有哪些啟動(dòng)方法,有什么區(qū)別,怎樣停用 Service

- 在
Service的生命周期中,被回調(diào)的方法比Activity少一些,只有onCreate,onStartCommand,onDestroy,onBind和onUnbind。
- 通常有兩種方式啟動(dòng)一個(gè)
Service, 他們對Service生命周期的影響是不一樣的。
2.3.1 通過 startService

-
Service會(huì)經(jīng)歷onCreate到onStartCommand,然后處于運(yùn)行狀態(tài),stopService的時(shí)候調(diào)用onDestroy
方法。
如果是調(diào)用者自己直接退出而沒有調(diào)用
stopService的話,Service會(huì)一直在后臺(tái)運(yùn)行。
2.3.2 通過 bindService

Service 會(huì)運(yùn)行 onCreate ,然后是調(diào)用 onBind , 這個(gè)時(shí)候調(diào)用者和 Service 綁定在一起。調(diào)用者退出了,Srevice 就會(huì)調(diào)用 onUnbind -> onDestroyed 方法。
所謂綁定在一起就共存亡了。調(diào)用者也可以通過調(diào)用
unbindService方法來停止服務(wù),這時(shí)候Srevice就會(huì)調(diào)用onUnbind->onDestroyed方法。
2.3.3 需要注意的是如果這幾個(gè)方法交織在一起的話,會(huì)出現(xiàn)什么情況呢?

一個(gè)原則是
Service的onCreate的方法只會(huì)被調(diào)用一次,就是你無論多少次的startService又bindService,Service只被創(chuàng)建一次。如果先是
bind了,那么start的時(shí)候就直接運(yùn)行Service的onStartCommand方法,如果先是start,那么bind的時(shí)候就直接運(yùn)行onBind方法。如果
service運(yùn)行期間調(diào)用了bindService,這時(shí)候再調(diào)用stopService的話,service是不會(huì)調(diào)用onDestroy方法的,service就stop不掉了,只能調(diào)用UnbindService,service就會(huì)被銷毀如果一個(gè)
service通過startService被start之后,多次調(diào)用startService的話,service會(huì)多次調(diào)
用onStartCommand方法。多次調(diào)用stopService的話,service只會(huì)調(diào)用一次onDestroyed方法。如果一個(gè)
service通過bindService被start之后,多次調(diào)用bindService的話,service只會(huì)調(diào)用一次onBind方法。多次調(diào)用unbindService的話會(huì)拋出異常。
第三篇:Service 與 Thread

3.1 Service 和 Thread 的區(qū)別

3.1.1 首先第一點(diǎn)定義上

-
thread是程序執(zhí)行的最小單元,他是分配cpu的基本單位安卓系統(tǒng)中,我們常說的主線程,UI線程,也是線程的一種。當(dāng)然,線程里面還可以執(zhí)行一些耗時(shí)的異步操作。 - 而
service大家記住,它是安卓中的一種特殊機(jī)制,service是運(yùn)行在主線程當(dāng)中的,所以說它不能做耗時(shí)操作,它是由系統(tǒng)進(jìn)程托管,其實(shí)service也是一種輕量級的IPC通信,因?yàn)?activity可以和service綁定,可以和service進(jìn)行數(shù)據(jù)通信。 - 而且有一種情況,
activity和service是處于不同的進(jìn)程當(dāng)中,所以說它們之間的數(shù)據(jù)通信,要通過IPC進(jìn)程間通信的機(jī)制來進(jìn)行操作。
3.1.2 第二點(diǎn)是在實(shí)際開發(fā)的過程當(dāng)中

- 在安卓系統(tǒng)當(dāng)中,線程一般指的是工作線程,就是后臺(tái)線程,做一些耗時(shí)操作的線程,而主線程是一種特殊的線程,它只是負(fù)責(zé)處理一些
UI線程的繪制,UI線程里面絕對不能做耗時(shí)操作,這里是最基本最重要的一點(diǎn)。(這是Thread在實(shí)際開發(fā)過程當(dāng)中的應(yīng)用) - 而
service是安卓當(dāng)中,四大組件之一,一般情況下也是運(yùn)行在主線程當(dāng)中,因此service也是不可以做耗時(shí)操作的,否則系統(tǒng)會(huì)報(bào) ANR 異常(ANR全稱:Application Not Responding),就是程序無法做出響應(yīng)。 - 如果一定要在
service里面進(jìn)行耗時(shí)操作,一定要記得開啟單獨(dú)的線程去做。
3.1.3 第三點(diǎn)是應(yīng)用場景上

- 當(dāng)你需要執(zhí)行耗時(shí)的網(wǎng)絡(luò),或者這種文件數(shù)據(jù)的查詢,以及其它阻塞
UI線程的時(shí)候,都應(yīng)該使用工作線程,也就是開啟一個(gè)子線程的方式。 - 這樣才能保證
UI線程不被占用,而影響用戶體驗(yàn)。 - 而
service來說,我們經(jīng)常需要長時(shí)間在后臺(tái)運(yùn)行,而且不需要進(jìn)行交互的情況下才會(huì)使用到服務(wù),比如說,我們在后臺(tái)播放音樂,開啟天氣預(yù)報(bào)的統(tǒng)計(jì),還有一些數(shù)據(jù)的統(tǒng)計(jì)等等。
3.2 為什么要用 Service 而不是 Thread

-
Thread的運(yùn)行是獨(dú)立于Activity的,也就是當(dāng)一個(gè)Activity被finish之后,如果沒有主動(dòng)停止Thread或者Thread中的run沒有執(zhí)行完畢時(shí)那么這個(gè)線程會(huì)一直執(zhí)行下去。 - 因此這里會(huì)出現(xiàn)一個(gè)問題:當(dāng)
Activity被finish之后,你不再持有該Thread的引用。 - 另一方面,你沒有辦法在不同的
Activity中對同一Thread進(jìn)行控制。
3.3 Service 里面是否能執(zhí)行耗時(shí)的操作
service 里面不能執(zhí)行耗時(shí)的操作(網(wǎng)絡(luò)請求,拷貝數(shù)據(jù)庫,大文件 )
Service不是獨(dú)立的進(jìn)程,也不是獨(dú)立的線程,它是依賴于應(yīng)用程序的主線程的,也就是說,在更多時(shí)候不建議在Service中編寫耗時(shí)的邏輯和操作(比如:網(wǎng)絡(luò)請求,拷貝數(shù)據(jù)庫,大文件),否則會(huì)引起ANR。如果想在服務(wù)中執(zhí)行耗時(shí)的任務(wù)。有以下解決方案:
- 在
service中開啟一個(gè)子線程
new Thread(){}.start();
- 可以使用
IntentService異步管理服務(wù)( 有關(guān)IntentService的內(nèi)容在后文中給出 )
3.4 Service 是否在 main thread 中執(zhí)行

- 默認(rèn)情況, 如果沒有顯示的指
service所運(yùn)行的進(jìn)程,Service和activity是運(yùn) 行在當(dāng)前app所在進(jìn)程的main thread(UI主線程)里面。 -
Service和Activity在同一個(gè)線程,對于同一app來說默認(rèn)情況下是在同一個(gè)線程中的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è)置為前臺(tái)進(jìn)程
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Notification notification = new Notification(R.mipmap.ic_launcher, "服務(wù)正在運(yùn)行",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ā)送鬧鐘廣播, 接收的時(shí)候調(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í)行時(shí)間,以毫秒為單位
* go off, using the appropriate clock (depending on the alarm type).
* @param intervalMillis 表示兩次鬧鐘執(zhí)行的間隔時(shí)間,也是以毫秒為單位
* of the alarm.
* @param operation 綁定了鬧鐘的執(zhí)行動(dòng)作,比如發(fā)送一個(gè)廣播、給出提示等等
*/
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)存清除等手段后仍然保持運(yùn)行的方法,有些手機(jī)廠商把這些知名的app放入了自己的白名單中,保證了進(jìn)程不死來提高用戶體驗(yàn)(如微信、app一樣躲避不了被殺的命運(yùn)。
第四篇:InterService
- 作為一個(gè)老司機(jī),如果連
Interservice都沒聽說過,那就有點(diǎn)那個(gè)啥了

4.1 什么是 IntentService

IntentService是Service的子類,比普通的Service增加了額外的功能。我們常用的
Service存在兩個(gè)問題:
Service不會(huì)專門啟動(dòng)一條單獨(dú)的進(jìn)程,Service與它所在應(yīng)用位于同一個(gè)進(jìn)程中Service也不是專門一條新線程,因此不應(yīng)該在Service中直接處理耗時(shí)的任務(wù)
4.2 IntentService 的特征

會(huì)創(chuàng)建獨(dú)立的
worker線程來處理所有的Intent請求會(huì)創(chuàng)建獨(dú)立的
worker線程來處理onHandleIntent()方法實(shí)現(xiàn)的代碼,無需處理多線程問題所有請求處理完成后,
IntentService會(huì)自動(dòng)停止,無需調(diào)用stopSelf()方法停止Service為
Service的onBind()提供默認(rèn)實(shí)現(xiàn),返回null為
Service的onStartCommand提供默認(rèn)實(shí)現(xiàn),將請求Intent添加到隊(duì)列中
4.3 Service 和 IntentService 區(qū)別

4.3.1 Service 是用于后臺(tái)服務(wù)的
- 當(dāng)應(yīng)用程序被掛到后臺(tái)的時(shí)候,為了保證應(yīng)用某些組件仍然可以工作而引入了
Service這個(gè)概念 - 那么這里面要強(qiáng)調(diào)的是:
Service不是獨(dú)立的進(jìn)程,也不是獨(dú)立的線程,它是依賴于應(yīng)用程序的主線程的,也就是說,在更多時(shí)候不建議在Service中編寫耗時(shí)的邏輯和操作,否則會(huì)引起ANR。
也就是,service 里面不可以進(jìn)行耗時(shí)的操作。雖然在后臺(tái)服務(wù)。但是也是在主線程里面。
4.3.2 當(dāng)我們編寫的耗時(shí)邏輯,不得不被 service 來管理的時(shí)候,就需要引入 IntentService 。

-
IntentService是繼承Service的,那么它包含了Service的全部特性,當(dāng)然也包含service的生命周期。 - 那么與
service不同的是,IntentService在執(zhí)行onCreate操作的時(shí)候,內(nèi)部開了一個(gè)線程,去你執(zhí)行你的耗時(shí)操作。
4.3.3 使用:

- 重寫
protected abstract void onHandleIntent(Intent intent)
4.3.4 IntentService 是一個(gè)通過 Context.startService(Intent) 啟動(dòng)可以處理異步請求的 Service

- 使用時(shí)你只需要繼承
IntentService和重寫其中的onHandleIntent(Intent)方法接收一個(gè)Intent對象 , 在適當(dāng)?shù)臅r(shí)候會(huì)停止自己 ( 一般在工作完成的時(shí)候 ) 。 - 所有的請求的處理都在一個(gè)工作線程中完成 , 它們會(huì)交替執(zhí)行 ( 但不會(huì)阻塞主線程的執(zhí)行 ) ,一次只能執(zhí)行一個(gè)請求。
4.3.5 是一個(gè)基于消息的服務(wù)

- 每次啟動(dòng)該服務(wù)并不是馬上處理你的工作,而是首先會(huì)創(chuàng)建對應(yīng)的
Looper,Handler并且在MessageQueue中添加的附帶客戶Intent的Message對象。 - 當(dāng)
Looper發(fā)現(xiàn)有Message的時(shí)候接著得到Intent對象通過在onHandleIntent((Intent)msg.obj)中調(diào)用你的處理程序,處理完后即會(huì)停止自己的服務(wù)。 - 意思是
Intent的生命周期跟你的處理的任務(wù)是一致的,所以這個(gè)類用下載任務(wù)中非常好,下載任務(wù)結(jié)束后服務(wù)自身就會(huì)結(jié)束退出。
4.3.6 總結(jié) IntentService 的特征有:

會(huì)創(chuàng)建獨(dú)立的
worker線程來處理所有的Intent請求;會(huì)創(chuàng)建獨(dú)立的
worker線程來處理onHandleIntent()方法實(shí)現(xiàn)的代碼,無需處理多線程問題;所有請求處理完成后,
IntentService會(huì)自動(dòng)停止,無需調(diào)用stopSelf()方法停止Service;
第五篇:Service 與 Activity

5.1 Activity 怎么和 Service 綁定,怎么在 Activity 中啟動(dòng)對應(yīng)的 Service

Activity通過bindService(Intent service, ServiceConnection conn, int flags)跟Service進(jìn)行綁定,當(dāng)綁定成功的時(shí)候Service會(huì)將代理對象通過回調(diào)的形式傳給conn,這樣我們就拿到了Service提供的服務(wù)代理對象。在
Activity中可以通過startService和bindService方法啟動(dòng)Service。一般情況下如果想獲取Service的服務(wù)對象那么肯定需要通過bindService()方法,比如音樂播放器,第三方支付等。如果僅僅只是為了開啟一個(gè)后臺(tái)任務(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é)后臺(tái)任務(wù)的處理。Activity和Service之間可以通過Intent傳遞數(shù)據(jù),因此可以把Intent看作是通信使者。
5.3 Service 和 Activity 在同一個(gè)線程嗎

對于同一 app 來說默認(rèn)情況下是在同一個(gè)線程中的,main Thread ( UI Thread )。
5.4 Service 里面可以彈吐司么

- 可以
- 彈吐司有個(gè)條件是:得有一個(gè)
Context上下文,而Service本身就是Context的子類 - 因此在
Service里面彈吐司是完全可以的。比如我們在Service中完成下載任務(wù)后可以彈一個(gè)吐司通知給用戶。
5.5 與 Service 交互方式

5.5.1 廣播交互

-
Server端將目前的下載進(jìn)度,通過廣播的方式發(fā)送出來,Client端注冊此廣播的監(jiān)聽器,當(dāng)獲取到該廣播后,將廣播中當(dāng)前的下載進(jìn)度解析出來并更新到界面上。 - 定義自己的廣播,這樣在不同的
Activity、Service以及應(yīng)用程序之間,就可以通過廣播來實(shí)現(xiàn)交互。
5.5.2 共享文件交互

- 我們使用
SharedPreferences來實(shí)現(xiàn)共享,當(dāng)然也可以使用其它IO方法實(shí)現(xiàn),通過這種方式實(shí)現(xiàn)交互時(shí)需要注意,對于文件的讀寫的時(shí)候,同一時(shí)間只能一方讀一方寫,不能兩方同時(shí)寫。 -
Server端將當(dāng)前下載進(jìn)度寫入共享文件中,Client端通過讀取共享文件中的下載進(jìn)度,并更新到主界面上。
5.5.3 Messenger 交互 ( 信使交互 )

-
Messenger翻譯過來指的是信使,它引用了一個(gè)Handler對象,別人能夠向它發(fā)送消息 ( 使用mMessenger.send ( Message msg )方法)。 - 該類允許跨進(jìn)程間基于
Message通信,在服務(wù)端使用Handler創(chuàng)建一個(gè)Messenger,客戶端只要獲得這個(gè)服務(wù)端的Messenger對象就可以與服務(wù)端通信了 - 在
Server端與 Client 端之間通過一個(gè)Messenger對象來傳遞消息,該對象類似于信息中轉(zhuǎn)站,所有信息通過該對象攜帶
5.5.4 自定義接口交互

- 其實(shí)就是我們自己通過接口的實(shí)現(xiàn)來達(dá)到
Activity與Service交互的目的,我們通過在Activity和Service之間架設(shè)一座橋樑,從而達(dá)到數(shù)據(jù)交互的目的,而這種實(shí)現(xiàn)方式和AIDL非常類似 - 自定義一個(gè)接口,該接口中有一個(gè)獲取當(dāng)前下載進(jìn)度的空方法。
Server端用一個(gè)類繼承自Binder并實(shí)現(xiàn)該接口,覆寫了其中獲取當(dāng)前下載進(jìn)度的方法。Client端通過ServiceConnection獲取到該類的對象,從而能夠使用該獲取當(dāng)前下載進(jìn)度的方法,最終實(shí)現(xiàn)實(shí)時(shí)交互。
5.5.5 AIDL 交互

- 遠(yuǎn)程服務(wù)一般通過
AIDL來實(shí)現(xiàn),可以進(jìn)行進(jìn)程間通信,這種服務(wù)也就是遠(yuǎn)程服務(wù)。 -
AIDL屬于Android的IPC機(jī)制,常用于跨進(jìn)程通信,主要實(shí)現(xiàn)原理基于底層Binder機(jī)制。
第六篇:使用

6.1 什么情況下會(huì)使用 Service

6.1.1 經(jīng)驗(yàn)總結(jié):

-
Service其實(shí)就是背地搞事情,又不想讓別人知道 - 舉一個(gè)生活當(dāng)中的例子,你想知道一件事情不需要直接去問,你可以通過側(cè)面了解。這就是
Service設(shè)計(jì)的初衷
6.1.2 Service 為什么被設(shè)計(jì)出來

- 根據(jù)
Service的定義,我們可以知道需要長期在后臺(tái)進(jìn)行的工作我們需要將其放在Service中去做。 - 得再通熟易懂一點(diǎn),就是不能放在
Activity中來執(zhí)行的工作就必須得放到Service中去做。 - 如:音樂播放、下載、上傳大文件、定時(shí)關(guān)閉應(yīng)用等功能。這些功能如果放到
Activity中做的話,那么Activity退出被銷毀了的話,那這些功能也就停止了,這顯然是不符合我們的設(shè)計(jì)要求的,所以要將他們放在Service中去執(zhí)行。
6.2 onStartCommand() 返回值 int 值的區(qū)別
- 有四種返回值,不同值代表的意思如下:

6.2.1 START_STICKY :
- 如果
service進(jìn)程被 kill 掉,保留service的狀態(tài)為開始狀態(tài),但不保留遞送的intent對象。 - 隨后系統(tǒng)會(huì)嘗試重新創(chuàng)建
service, 由于服務(wù)狀態(tài)為開始狀態(tài),所以創(chuàng)建服務(wù)后一定會(huì)調(diào)用onStartCommand ( Intent, int, int )方法。 - 如果在此期間沒有任何啟動(dòng)命令被傳遞到
service, 那么參數(shù)Intent將為null。
6.2.2 START_NOT_STICKY :
- “非粘性的”。
- 使用這個(gè)返回值時(shí) , 如果在執(zhí)行完
onStartCommand后 , 服務(wù)被異常kill掉 ,系統(tǒng)不會(huì)自動(dòng)重啟該服務(wù)。
6.2.3 START_REDELIVER_INTENT:
- 重傳
Intent。 - 使用這個(gè)返回值時(shí),如果在執(zhí)行完
onStartCommand后,服務(wù)被異常 kill 掉 - 系統(tǒng)會(huì)自動(dò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”這個(gè)屬性設(shè)置最高優(yōu)先級,1000是最高值,如果數(shù)字越小則優(yōu)先級越低,同時(shí)實(shí)用于廣播。在
onStartCommand里面調(diào)用startForeground()方法把Service提升為前臺(tái)進(jìn)程級別,然后再onDestroy里面要記得調(diào)用stopForeground ()方法。onStartCommand方法,手動(dòng)返回START_STICKY。

- 在
onDestroy方法里發(fā)廣播重啟service。
-
service+broadcast方式,就是當(dāng)service走ondestory的時(shí)候,發(fā)送一個(gè)自定義的廣播 - 當(dāng)收到廣播的時(shí)候,重新啟動(dòng)
service。( 第三方應(yīng)用或是在setting里-應(yīng)用強(qiáng)制停止時(shí),APP進(jìn)程就直接被干掉了,onDestroy方法都進(jìn)不來,所以無法保證會(huì)執(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 ) 方法在什么情況下會(huì)執(zhí)行

- 如果在
onUnbind()方法返回true的情況下會(huì)執(zhí)行 , 否則不執(zhí)行。
總結(jié)
- 本文基本涵蓋了
Android Service相關(guān)的知識(shí)點(diǎn)。由于篇幅原因,諸如 InterService 具體使用方法等,沒辦法詳細(xì)的介紹,大家很容易就能在網(wǎng)上找到資料進(jìn)行學(xué)習(xí)。 -
重點(diǎn):關(guān)于Android的四大組件,到現(xiàn)在為止我才總結(jié)完Activity和Service,我將繼續(xù)針對,BroadcastRecevierContentProvider等,以及四大組件之外的,事件分發(fā)、滑動(dòng)沖突、新能優(yōu)化等重要模塊,進(jìn)行全面總結(jié),歡迎大家關(guān)注 _yuanhao 的 簡書,方便及時(shí)接收更新 - 開始前還以為總結(jié)不難,實(shí)際寫文章的過程中,才知道什么是艱辛。也不知道自己能不能咬牙堅(jiān)持下去,希望大家給我鼓勵(lì),就算只是一個(gè)贊,也是我堅(jiān)持下去的理由!
碼字不易,你的點(diǎn)贊是我總結(jié)的最大動(dòng)力!
由于我在「稀土掘金」「簡書」「
CSDN」「博客園」等站點(diǎn),都有新內(nèi)容發(fā)布。所以大家可以直接關(guān)注我的GitHub倉庫,以免錯(cuò)過精彩內(nèi)容!1W多字長文,加上精美思維導(dǎo)圖,記得點(diǎn)贊哦,歡迎關(guān)注 _yuanhao 的 簡書相關(guān)文章均可在我的主頁、GitHub 上看到,這里限于篇幅原因,也為了保持界面整潔,讓大家能有跟舒心的閱讀體驗(yàn)就不給出了,我們下篇文章不見不散!
