Android Service生命周期詳解
前言
Service是Android系統(tǒng)的四大組件之一。在Android系統(tǒng)中,Service可以用來執(zhí)行一些需要在后臺(tái)長期運(yùn)行的任務(wù),也可以用來為其它應(yīng)用提供一些服務(wù)。Service的使用方式主要有兩種:startService()和bindService()。這兩種方式下Service的生命周期不大相同。通過熟悉Service的生命周期,我們可以更加深刻地理解Android系統(tǒng)中Service的工作機(jī)制。
基礎(chǔ)知識(shí)
一個(gè)Service不是一個(gè)單獨(dú)的進(jìn)程。Service本身不是運(yùn)行在一個(gè)單獨(dú)的進(jìn)程中,除非在AndroidManifest.xml文件中指定了android:process屬性。默認(rèn)情況下,Service運(yùn)行在應(yīng)用所在的那個(gè)進(jìn)程中。一個(gè)Service也不是一個(gè)線程。Service運(yùn)行在應(yīng)用的主線程中,所以如果要執(zhí)行耗時(shí)的后臺(tái)任務(wù)那么需要在子線程之中執(zhí)行。
Service的生命周期
根據(jù)使用方式的不同,Service的生命周期可以分成2條路徑,具體可以看下面這張引用自Android官網(wǎng)的圖:

下面詳細(xì)分析一下這些回調(diào)方法。
- onCreate() 當(dāng)Service被創(chuàng)建時(shí)回調(diào)。如果Service已經(jīng)在運(yùn)行,那么不會(huì)回調(diào)onCreate()方法。在onCreate()方法中,我們可以做一些初始化操作。
- onStartCommand() 當(dāng)有組件調(diào)用startService()方法啟動(dòng)Service時(shí)回調(diào)。在onStartCommand()方法中,我們可以執(zhí)行后臺(tái)任務(wù)。由于Service是運(yùn)行在主線程之中的,所以如果是耗時(shí)的任務(wù)那么需要使用子線程來執(zhí)行任務(wù)。在Service完成任務(wù)之后,需要有組件調(diào)用stopService()方法來停止Service,或者由Service調(diào)用stopSelf()方法來自行停止。
- onBind() 當(dāng)有組件調(diào)用bindService()方法與Service綁定時(shí)回調(diào)。在onBind()方法中,你可以通過返回一個(gè)IBinder對(duì)象來提供一個(gè)接口供客戶端與Service進(jìn)行通信。
- onUnbind() 當(dāng)客戶端調(diào)用unbindService()方法與Service解除綁定時(shí)回調(diào)。
- onDestroy() 當(dāng)Service停止運(yùn)行將被銷毀時(shí)回調(diào)。當(dāng)有組件調(diào)用startService()方法來啟動(dòng)Service時(shí),Service開始運(yùn)行。直到有組件調(diào)用stopService()方法來停止Service,或者由Service調(diào)用stopSelf()方法來自行停止。當(dāng)有組件調(diào)用bindService()方法與Service綁定時(shí),Service開始運(yùn)行。直到所有的客戶端與Service解綁時(shí),Service停止運(yùn)行。在onDestroy()方法中,我們應(yīng)該釋放所有的資源,比如子線程、注冊(cè)的監(jiān)聽器和廣播接收器等。
總結(jié)
根據(jù)使用方式的不同,Service的生命周期可以分成2條路徑:
- 啟動(dòng)Service Service在有組件調(diào)用startService()方法時(shí)創(chuàng)建,然后一直運(yùn)行下去。組件可以通過調(diào)用stopService()方法來停止Service,或者Service調(diào)用stopSelf()方法來自行停止。Service停止之后,系統(tǒng)會(huì)將其銷毀。
- 綁定Service Service在有組件調(diào)用bindService()方法時(shí)創(chuàng)建。然后客戶端可以通過IBinder接口與Service進(jìn)行通信。客戶端可以通過調(diào)用unbindService()方法來解除綁定。多個(gè)客戶端可以綁定到同一個(gè)Service,當(dāng)所有的客戶端與Service解綁時(shí),系統(tǒng)會(huì)銷毀該Service。
注意:Service可以同時(shí)以這兩種方式運(yùn)行,也就是說,調(diào)用startService()方法啟動(dòng)Service的同時(shí)可以調(diào)用bindService()方法綁定Service。這種情況下,只有當(dāng)所有客戶端都解除綁定,并且有組件調(diào)用stopService()方法或者Service調(diào)用stopSelf()方法才可以停止Service。
我們可以總結(jié)出Service的2個(gè)生命期:
- 完整生命期 從onCreate()方法回調(diào)開始,直到onDestroy()方法回調(diào)結(jié)束。與Activity類似,Service也在onCreate()方法中完成初始化工作,并在onDestroy()方法中釋放所有資源。
- 活動(dòng)生命期 從onStartCommand()或者onBind()方法回調(diào)開始。對(duì)于啟動(dòng)Service,活動(dòng)生命期與完整生命期同時(shí)結(jié)束。對(duì)于綁定Service,活動(dòng)生命期在onUnbind()方法回調(diào)時(shí)結(jié)束。
例子
這里舉一個(gè)例子來實(shí)踐Service的生命周期。例子代碼地址:https://github.com/chongyucaiyan/ServiceDemo
demo頁面如下圖所示:

四個(gè)按鈕分別用來啟動(dòng)Service,停止Service,綁定Service和解綁Service。
首先,我們實(shí)踐下啟動(dòng)Service的生命周期。點(diǎn)擊Start Service按鈕啟動(dòng)Service。使用LocalService關(guān)鍵字過濾,打印的日志如下圖所示:

可以看到Service依次回調(diào)了onCreate()和onStartCommand()方法,并且兩個(gè)方法都是在主線程之中執(zhí)行的。接著再點(diǎn)擊兩次Start Service按鈕,打印的日志如下圖所示:

可以看到Service運(yùn)行之后,再次啟動(dòng)Service不會(huì)再回調(diào)onCreate()方法,只會(huì)回調(diào)onStartCommand()方法。最后點(diǎn)擊Stop Service按鈕停止Service,打印的日志如下圖所示:

可以看到停止Service后,Service回調(diào)了onDestroy()方法。
然后,我們實(shí)踐下綁定Service的生命周期。點(diǎn)擊Bind Service按鈕綁定Service。打印的日志如下圖所示:

可以看到Service依次回調(diào)了onCreate()和onBind()方法。接著再點(diǎn)擊兩次Bind Service按鈕,可以看到Service不再回調(diào)onBind()方法,因?yàn)橥粋€(gè)組件同一時(shí)間只能綁定一次。最后單擊Unbind Service按鈕解綁Service,打印的日志如下圖所示:

可以看到Service依次回調(diào)了onUnbind()和onDestroy()方法。
最后,我們實(shí)踐下同時(shí)以兩種方式操作Service的生命周期。點(diǎn)擊Start Service按鈕啟動(dòng)Service,點(diǎn)擊Bind Service按鈕綁定Service,打印的日志如下圖所示:

可以看到啟動(dòng)Service回調(diào)了onStartCommand()方法,綁定Service回調(diào)了onBind()方法,Service正常運(yùn)行。這種情況下,只有客戶端解除綁定,并且組件調(diào)用stopService()方法,才可以停止Service。依次點(diǎn)擊Unbind Service和Stop Service按鈕,打印的日志如下圖所示:

可以看到只有上述兩種操作都執(zhí)行完畢之后,Service才回調(diào)了onDestroy()方法。
參考
- https://developer.android.com/reference/android/app/Service.html
- https://developer.android.com/guide/components/services.html
到此這篇關(guān)于Android Service生命周期詳解的文章就介紹到這了,更多相關(guān)Android Service生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android RatingBar星星評(píng)分控件實(shí)例代碼
本文通過實(shí)例代碼給大家介紹了Android RatingBar星星評(píng)分控件,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-06-06
初學(xué)Android之網(wǎng)絡(luò)封裝實(shí)例
大家好,本篇文章主要講的是初學(xué)Android之網(wǎng)絡(luò)封裝實(shí)例,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
Android中TextView顯示圓圈背景或設(shè)置圓角的方法
TextView顯示文本給用戶,并允許他們選擇編輯。TextView是一個(gè)完整的文本編輯器,但是其基本類配置為不允許編輯。下面這篇文章主要給大家介紹了關(guān)于Android中TextView顯示圓圈背景或設(shè)置圓角的方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-05-05
Android Fragment 和 FragmentManager 的代碼分析
這篇文章主要介紹了Android Fragment 和 FragmentManager 的代碼分析,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-01-01
Android 滑動(dòng)監(jiān)聽的實(shí)例詳解
這篇文章主要介紹了Android 滑動(dòng)監(jiān)聽的實(shí)例詳解的相關(guān)資料,希望通過本能幫助到大家,需要的朋友可以參考下2017-09-09
Android基于service實(shí)現(xiàn)音樂的后臺(tái)播放功能示例
這篇文章主要介紹了Android基于service實(shí)現(xiàn)音樂的后臺(tái)播放功能,結(jié)合實(shí)例形式分析了Android基于Service組件實(shí)現(xiàn)多媒體音頻播放功能的步驟與相關(guān)操作技巧,需要的朋友可以參考下2016-10-10
Android開發(fā)之InetAddress基礎(chǔ)入門簡介與源碼實(shí)例
這篇文章主要介紹了Android開發(fā)之InetAddress基礎(chǔ)入門簡介,需要的朋友可以參考下2020-03-03
Android實(shí)現(xiàn)TextView字符串關(guān)鍵字變色的方法
這篇文章顯示給大家介紹了字符串中關(guān)鍵字變色的實(shí)現(xiàn)方法,而后又拓展介紹了在Android中如何實(shí)現(xiàn)搜索關(guān)鍵字變色,相信對(duì)各位Android開發(fā)者們具有一定的參考借鑒價(jià)值,感興趣的朋友們下面來一起看看吧。2016-10-10
基于android中的各種顏色在drawable.xml中的值詳解
本篇文章是對(duì)在android中的各種顏色在drawable.xml中的值進(jìn)行了詳細(xì)的介紹。需要的朋友參考下2013-05-05

