Service的啟動(dòng)過程
Service的啟動(dòng)和根Activity的啟動(dòng)很類似。Service的啟動(dòng)同樣需要保證該應(yīng)用程序的進(jìn)程已經(jīng)被啟動(dòng)。
啟動(dòng)大綱
ContextImpl請(qǐng)求AMS啟動(dòng)Service.
AMS請(qǐng)求ActivityThread啟動(dòng)Service.
ContextImpl請(qǐng)求AMS啟動(dòng)Service
當(dāng)我們需要啟動(dòng)一個(gè)Service時(shí),我們會(huì)使用
context.startService。而Context只是一個(gè)抽象的類,它的實(shí)現(xiàn)是在ContextWrapper中。在ContextWrapper的
startService方法中,又會(huì)調(diào)用其內(nèi)部的Context類型的mBase變量,而該變量的創(chuàng)建詳見ActivityThread的createBaseContextForActivity方法,它的實(shí)現(xiàn)類是ContextImpl。在ContextImpl的
startService方法中,又會(huì)調(diào)用其自身的startServiceCommon方法。在ContextImpl的
startServiceCommon方法中,會(huì)使用ActivityManager獲取AMS的代理IActivityManager,并調(diào)用其startService方法。
AMS請(qǐng)求ActivityThread啟動(dòng)Service
AMS的
startService方法中調(diào)用ActiveService的startServiceLocked方法,其中調(diào)用retrieveServiceLocked用于獲取啟動(dòng)服務(wù)的Intent參數(shù)所對(duì)應(yīng)的ServiceRecord,它主要用于描述一個(gè)Service,啟動(dòng)Service所必須的參數(shù)。在ActiveService的
startServiceLocked方法中獲取到相應(yīng)的ServiceRecord之后,就會(huì)調(diào)用其自身的startServiceInnerLocked方法,而它又會(huì)去調(diào)用bringUpServiceLocked方法。在bringUpServiceLocked方法中主要做了以下三個(gè)工作:
(1)獲取Service運(yùn)行所在的進(jìn)程。
(2)如果Service運(yùn)行所在的應(yīng)用程序進(jìn)程ProcessRecord存在,則調(diào)用其自身的realStartServiceLocked方法來啟動(dòng)Service.
(3)如果Service運(yùn)行所在的應(yīng)用程序進(jìn)程ProcessRecord不存在,則需要調(diào)用AMS的startProcessLocked方法來啟動(dòng)應(yīng)用程序進(jìn)程。
在ActiveService的
realStartServiceLocked方法中,會(huì)使用ProcessRecord的IApplicationThread類型的引用(實(shí)現(xiàn)類是ActivityThread的內(nèi)部類ApplicationThread),調(diào)用其scheduleCreateService方法。在ActivityThread的
scheduleCreateService方法中,會(huì)向其內(nèi)部類并繼承自Handler的H發(fā)送CREATE_SERVICE消息,并由H進(jìn)行處理,最終會(huì)調(diào)用handleCreateService方法。在ActivityThread的
handleCreateService方法中主要做了如下幾件事:
(1)獲取要啟動(dòng)Service的應(yīng)用程序的LoadApk(包信息),并通過它獲取類的加載器,通過反射創(chuàng)建Service的實(shí)例。
(2)調(diào)用ContextImpl的createAppContext方法,為Service創(chuàng)建上下文環(huán)境ContextImpl對(duì)象。
(3)調(diào)用Service的attach方法,對(duì)Service進(jìn)行初始化。
(4)調(diào)用Service的onCreate方法,這樣Service就啟動(dòng)了。
Service的綁定過程
除了使用Context的startService來啟動(dòng)Service外,我們也可以通過Context的bindService來綁定Service。綁定Service的過程要比啟動(dòng)Service的過程復(fù)雜一些。
啟動(dòng)大綱
ContextImpl請(qǐng)求AMS綁定Service.
AMS請(qǐng)求ActivityThread處理Service綁定.
AMS進(jìn)行Service的綁定.
ContextImpl請(qǐng)求AMS綁定Service
當(dāng)我們需要綁定一個(gè)Service時(shí),我們會(huì)使用
context.bindService。而Context只是一個(gè)抽象的類,它的實(shí)現(xiàn)是在ContextWrapper中。在ContextWrapper的
bindService方法中,又會(huì)調(diào)用其內(nèi)部的Context類型的mBase變量,而該變量的創(chuàng)建詳見ActivityThread的createBaseContextForActivity方法,它的實(shí)現(xiàn)類是ContextImpl。在ContextImpl的
bindService方法中,又會(huì)調(diào)用其自身的bindServiceCommon方法。在ContextImpl的
bindServiceCommon方法中,首先調(diào)用LoadedApk的getServiceDispatcher方法獲取ServiceConnection的封裝類(本地的代理)IServiceConnection(用于跨進(jìn)程通信),然后使用ActivityManager獲取AMS的代理IActivityManager,調(diào)用其bindService方法并將IServiceConnection對(duì)象傳入。
AMS請(qǐng)求ActivityThread處理Service綁定
AMS的
bindService方法中調(diào)用方法中調(diào)用ActiveService的bindServiceLocked方法,其中同樣的和startServiceLocked一樣調(diào)用retrieveServiceLocked用于獲取啟動(dòng)服務(wù)的Intent參數(shù)所對(duì)應(yīng)的ServiceRecord,然后調(diào)用ServiceRecord的retrieveAppBindingLocked方法來獲取應(yīng)用和服務(wù)的綁定信息AppBindRecord,最后調(diào)用requestServiceBindingLocked方法,將之前獲取的AppBindRecord信息傳入,來發(fā)出服務(wù)綁定的請(qǐng)求。除此之外,在
bindServiceLocked方法調(diào)用requestServiceBindingLocked請(qǐng)求綁定前,還調(diào)用了bringUpServiceLocked方法去啟動(dòng)服務(wù)。在ActiveService的
requestServiceBindingLocked方法中最終會(huì)調(diào)用ActivityThread的scheduleBindService方法,然后封裝BindServiceData數(shù)據(jù)并將其傳入sendMessage方法中,向H發(fā)送BIND_SERVICE消息。在H對(duì)應(yīng)的消息處理中會(huì)調(diào)用handleBindService方法。在handleBindService方法中,對(duì)未綁定服務(wù)的,先后調(diào)用Service的onBind方法和AMS的publishService方法;對(duì)已綁定服務(wù)的,先后調(diào)用Service的onRebind方法和AMS的serviceDoneExecuting方法。
在AMS的publishService方法中又調(diào)用了
ActiveService的publishServiceLocked方法。在
publishServiceLocked方法中會(huì)調(diào)用IServiceConnection的connected方法來建立服務(wù)連接,最終會(huì)調(diào)用執(zhí)行LoadApk中的RunConnection任務(wù),執(zhí)行doConnected方法建立服務(wù)綁定連接。
與Service綁定相關(guān)的對(duì)象類型介紹:
ServiceRecord:用于描述一個(gè)Service。
ProcessRecord:一個(gè)進(jìn)程所包含的信息。
ConnectionRecord:用于描述應(yīng)用程序進(jìn)程和Service建立的一次通信。
AppBindRecord: 用于維護(hù)Service與應(yīng)用進(jìn)程之間的綁定信息。
IntentBindRecord:用于描述綁定Service的Intent信息。