Android应用程序绑定服务(bindService)的过程源代码分析
?? ? ? ?Android應(yīng)用程序組件Service與Activity一樣,既可以在新的進(jìn)程中啟動(dòng),也可以在應(yīng)用程序進(jìn)程內(nèi)部啟動(dòng);前面我們已經(jīng)分析了在新的進(jìn)程中啟動(dòng)Service的過(guò)程,本文將要介紹在應(yīng)用程序內(nèi)部綁定Service的過(guò)程,這是一種在應(yīng)用程序進(jìn)程內(nèi)部啟動(dòng)Service的方法。
《Android系統(tǒng)源代碼情景分析》一書(shū)正在進(jìn)擊的程序員網(wǎng)(http://0xcc0xcd.com)中連載,點(diǎn)擊進(jìn)入!
?? ? ? ?在前面一篇文章Android進(jìn)程間通信(IPC)機(jī)制Binder簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃中,我們就曾經(jīng)提到,在Android系統(tǒng)中,每一個(gè)應(yīng)用程序都是由一些Activity和Service組成的,一般Service運(yùn)行在獨(dú)立的進(jìn)程中,而Activity有可能運(yùn)行在同一個(gè)進(jìn)程中,也有可能運(yùn)行在不同的進(jìn)程中;在接下來(lái)的文章中,Android系統(tǒng)在新進(jìn)程中啟動(dòng)自定義服務(wù)過(guò)程(startService)的原理分析一文介紹了在新的進(jìn)程中啟動(dòng)Service的過(guò)程,Android應(yīng)用程序啟動(dòng)過(guò)程源代碼分析一文介紹了在新的進(jìn)程中啟動(dòng)Activity的過(guò)程,而Android應(yīng)用程序內(nèi)部啟動(dòng)Activity過(guò)程(startActivity)的源代碼分析一文則介紹了在應(yīng)用程序進(jìn)程內(nèi)部啟動(dòng)Activity的過(guò)程;本文接過(guò)最后一棒,繼續(xù)介紹在應(yīng)用程序進(jìn)程內(nèi)部啟動(dòng)Service的過(guò)程,這種過(guò)程又可以稱(chēng)在應(yīng)用程序進(jìn)程內(nèi)部綁定服務(wù)(bindService)的過(guò)程,這樣,讀者應(yīng)該就可以對(duì)Android應(yīng)用程序啟動(dòng)Activity和Service有一個(gè)充分的認(rèn)識(shí)了。
?? ? ? ?這里仍然是按照老規(guī)矩,通過(guò)具體的例子來(lái)分析Android應(yīng)用程序綁定Service的過(guò)程,而所使用的例子便是前面我們?cè)诮榻BAndroid系統(tǒng)廣播機(jī)制的一篇文章Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃中所開(kāi)發(fā)的應(yīng)用程序Broadcast了。
?? ? ? ?我們先簡(jiǎn)單回顧一下這個(gè)應(yīng)用程序?qū)嵗壎⊿ervice的過(guò)程。在這個(gè)應(yīng)用程序的MainActivity的onCreate函數(shù)中,會(huì)調(diào)用bindService來(lái)綁定一個(gè)計(jì)數(shù)器服務(wù)CounterService,這里綁定的意思其實(shí)就是在MainActivity內(nèi)部獲得CounterService的接口,所以,這個(gè)過(guò)程的第一步就是要把CounterService啟動(dòng)起來(lái)。當(dāng)CounterService的onCreate函數(shù)被調(diào)用起來(lái)了,就說(shuō)明CounterService已經(jīng)啟動(dòng)起來(lái)了,接下來(lái)系統(tǒng)還要調(diào)用CounterService的onBind函數(shù),跟CounterService要一個(gè)Binder對(duì)象,這個(gè)Binder對(duì)象是在CounterService內(nèi)部自定義的CounterBinder類(lèi)的一個(gè)實(shí)例,它繼承于Binder類(lèi),里面實(shí)現(xiàn)一個(gè)getService函數(shù),用來(lái)返回外部的CounterService接口。系統(tǒng)得到這個(gè)Binder對(duì)象之后,就會(huì)調(diào)用MainActivity在bindService函數(shù)里面?zhèn)鬟^(guò)來(lái)的ServiceConnection實(shí)例的onServiceConnected函數(shù),并把這個(gè)Binder對(duì)象以參數(shù)的形式傳到onServiceConnected函數(shù)里面,于是,MainActivity就可以調(diào)用這個(gè)Binder對(duì)象的getService函數(shù)來(lái)獲得CounterService的接口了。
?? ? ? ?這個(gè)過(guò)程比較復(fù)雜,但總體來(lái)說(shuō),思路還是比較清晰的,整個(gè)調(diào)用過(guò)程為MainActivity.bindService->CounterService.onCreate->CounterService.onBind->MainActivity.ServiceConnection.onServiceConnection->CounterService.CounterBinder.getService。下面,我們就先用一個(gè)序列圖來(lái)總體描述這個(gè)服務(wù)綁定的過(guò)程,然后就具體分析每一個(gè)步驟。
點(diǎn)擊查看大圖
?? ? ? ?Step 1. ContextWrapper.bindService
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/content/ContextWrapper.java文件中:
public class ContextWrapper extends Context {Context mBase;......@Overridepublic boolean bindService(Intent service, ServiceConnection conn,int flags) {return mBase.bindService(service, conn, flags);}...... }?? ? ? ?這里的mBase是一個(gè)ContextImpl實(shí)例變量,于是就調(diào)用ContextImpl的bindService函數(shù)來(lái)進(jìn)一步處理。?? ? ? ?Step 2.?ContextImpl.bindService
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ContextImpl.java文件中:
class ContextImpl extends Context {......@Overridepublic boolean bindService(Intent service, ServiceConnection conn,int flags) {IServiceConnection sd;if (mPackageInfo != null) {sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),mMainThread.getHandler(), flags);} else {......}try {int res = ActivityManagerNative.getDefault().bindService(mMainThread.getApplicationThread(), getActivityToken(),service, service.resolveTypeIfNeeded(getContentResolver()),sd, flags);......return res != 0;} catch (RemoteException e) {return false;}}......}?? ? ? ?這里的mMainThread是一個(gè)ActivityThread實(shí)例,通過(guò)它的getHandler函數(shù)可以獲得一個(gè)Handler對(duì)象,有了這個(gè)Handler對(duì)象后,就可以把消息分發(fā)到ActivityThread所在的線(xiàn)程消息隊(duì)列中去了,后面我們將會(huì)看到這個(gè)用法,現(xiàn)在我們暫時(shí)不關(guān)注,只要知道這里從ActivityThread處獲得了一個(gè)Handler并且保存在下面要介紹的ServiceDispatcher中去就可以了。?? ? ? ?我們先看一下ActivityThread.getHandler的實(shí)現(xiàn),然后再回到這里的bindService函數(shù)來(lái)。
?? ? ? ?Step 3. ActivityThread.getHandler
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
public final class ActivityThread {......final H mH = new H();......private final class H extends Handler {......public void handleMessage(Message msg) {......}......}......final Handler getHandler() {return mH;}...... }?? ? ? ?這里返回的Handler是在ActivityThread類(lèi)內(nèi)部從Handler類(lèi)繼承下來(lái)的一個(gè)H類(lèi)實(shí)例變量。?? ? ? ?回到Step 2中的ContextImpl.bindService函數(shù)中,獲得了這個(gè)Handler對(duì)象后,就調(diào)用mPackageInfo.getServiceDispatcher函數(shù)來(lái)獲得一個(gè)IServiceConnection接口,這里的mPackageInfo的類(lèi)型是LoadedApk,我們來(lái)看看它的getServiceDispatcher函數(shù)的實(shí)現(xiàn),然后再回到ContextImpl.bindService函數(shù)來(lái)。
?? ? ? ?Step 4. LoadedApk.getServiceDispatcher
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:
final class LoadedApk {......public final IServiceConnection getServiceDispatcher(ServiceConnection c,Context context, Handler handler, int flags) {synchronized (mServices) {LoadedApk.ServiceDispatcher sd = null;HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);if (map != null) {sd = map.get(c);}if (sd == null) {sd = new ServiceDispatcher(c, context, handler, flags);if (map == null) {map = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>();mServices.put(context, map);}map.put(c, sd);} else {sd.validate(context, handler);}return sd.getIServiceConnection();}}......static final class ServiceDispatcher {private final ServiceDispatcher.InnerConnection mIServiceConnection;private final ServiceConnection mConnection;private final Handler mActivityThread;......private static class InnerConnection extends IServiceConnection.Stub {final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;......InnerConnection(LoadedApk.ServiceDispatcher sd) {mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);}......}......ServiceDispatcher(ServiceConnection conn,Context context, Handler activityThread, int flags) {mIServiceConnection = new InnerConnection(this);mConnection = conn;mActivityThread = activityThread;......}......IServiceConnection getIServiceConnection() {return mIServiceConnection;}......}...... }?? ? ? ? 在getServiceDispatcher函數(shù)中,傳進(jìn)來(lái)的參數(shù)context是一個(gè)MainActivity實(shí)例,先以它為Key值在mServices中查看一下,是不是已經(jīng)存在相應(yīng)的ServiceDispatcher實(shí)例,如果有了,就不用創(chuàng)建了,直接取出來(lái)。在我們這個(gè)情景中,需要?jiǎng)?chuàng)建一個(gè)新的ServiceDispatcher。在創(chuàng)建新的ServiceDispatcher實(shí)例的過(guò)程中,將上面?zhèn)飨聛?lái)ServiceConnection參數(shù)c和Hanlder參數(shù)保存在了ServiceDispatcher實(shí)例的內(nèi)部,并且創(chuàng)建了一個(gè)InnerConnection對(duì)象,這是一個(gè)Binder對(duì)象,一會(huì)是要傳遞給ActivityManagerService的,ActivityManagerServic后續(xù)就是要通過(guò)這個(gè)Binder對(duì)象和ServiceConnection通信的。?? ? ? ?函數(shù)getServiceDispatcher最后就是返回了一個(gè)InnerConnection對(duì)象給ContextImpl.bindService函數(shù)。回到ContextImpl.bindService函數(shù)中,它接著就要調(diào)用ActivityManagerService的遠(yuǎn)程接口來(lái)進(jìn)一步處理了。
?? ? ? Step 5. ActivityManagerService.bindService
?? ? ??這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
?? ? ? ? Step 6. ActivityManagerService.bindService
?? ? ? ? 這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
?? ? ? ?接著通過(guò)retrieveServiceLocked函數(shù),得到一個(gè)ServiceRecord,這個(gè)ServiceReocrd描述的是一個(gè)Service對(duì)象,這里就是CounterService了,這是根據(jù)傳進(jìn)來(lái)的參數(shù)service的內(nèi)容獲得的。回憶一下在MainActivity.onCreate函數(shù)綁定服務(wù)的語(yǔ)句:
Intent bindIntent = new Intent(MainActivity.this, CounterService.class); bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);?? ? ? ?這里的參數(shù)service,就是上面的bindIntent了,它里面設(shè)置了CounterService類(lèi)的信息(CounterService.class),因此,這里可以通過(guò)它來(lái)把CounterService的信息取出來(lái),并且保存在ServiceRecord對(duì)象s中。?? ? ? ?接下來(lái),就是把傳進(jìn)來(lái)的參數(shù)connection封裝成一個(gè)ConnectionRecord對(duì)象。注意,這里的參數(shù)connection是一個(gè)Binder對(duì)象,它的類(lèi)型是LoadedApk.ServiceDispatcher.InnerConnection,是在Step 4中創(chuàng)建的,后續(xù)ActivityManagerService就是要通過(guò)它來(lái)告訴MainActivity,CounterService已經(jīng)啟動(dòng)起來(lái)了,因此,這里要把這個(gè)ConnectionRecord變量c保存下來(lái),它保在在好幾個(gè)地方,都是為了后面要用時(shí)方便地取回來(lái)的,這里就不仔細(xì)去研究了,只要知道ActivityManagerService要使用它時(shí)就可以方便地把它取出來(lái)就可以了,具體后面我們?cè)俜治觥?br />
?? ? ? ?最后,傳進(jìn)來(lái)的參數(shù)flags的位Context.BIND_AUTO_CREATE為1(參見(jiàn)上面MainActivity.onCreate函數(shù)調(diào)用bindService函數(shù)時(shí)設(shè)置的參數(shù)),因此,這里會(huì)調(diào)用bringUpServiceLocked函數(shù)進(jìn)一步處理。
?? ? ? ?Step 7.?ActivityManagerService.bringUpServiceLocked
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNativeimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {......private final boolean bringUpServiceLocked(ServiceRecord r,int intentFlags, boolean whileRestarting) {......final String appName = r.processName;ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);if (app != null && app.thread != null) {try {realStartServiceLocked(r, app);return true;} catch (RemoteException e) {......}}// Not running -- get it started, and enqueue this service record// to be executed when the app comes up.if (startProcessLocked(appName, r.appInfo, true, intentFlags,"service", r.name, false) == null) {......}......}...... }?? ? ? ?回憶在Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃中一文中,我們沒(méi)有在程序的AndroidManifest.xml配置文件中設(shè)置CounterService的process屬性值,因此,它默認(rèn)就為application標(biāo)簽的process屬性值,而application標(biāo)簽的process屬性值也沒(méi)有設(shè)置,于是,它們就默認(rèn)為應(yīng)用程序的包名了,即這里的appName的值為"shy.luo.broadcast"。接下來(lái)根據(jù)appName和應(yīng)用程序的uid值獲得一個(gè)ProcessRecord記錄,由于之前在啟動(dòng)MainActivity的時(shí)候,已經(jīng)根據(jù)這個(gè)appName和uid值創(chuàng)建了一個(gè)ProcessReocrd對(duì)象(具體可以參考Android應(yīng)用程序啟動(dòng)過(guò)程源代碼分析一文),因此,這里取回來(lái)的app和app.thread均不為null,于是,就執(zhí)行realStartServiceLocked函數(shù)來(lái)執(zhí)行下一步操作了。
?? ? ? ?如果這里得到的ProcessRecord變量app為null,又是什么情況呢?在這種情況下,就會(huì)執(zhí)行后面的startProcessLocked函數(shù)來(lái)創(chuàng)建一個(gè)新的進(jìn)程,然后在這個(gè)新的進(jìn)程中啟動(dòng)這個(gè)Service了,具體可以參考前面一篇文章Android系統(tǒng)在新進(jìn)程中啟動(dòng)自定義服務(wù)過(guò)程(startService)的原理分析。
?? ? ? ?Step 8.?ActivityManagerService.realStartServiceLocked
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNativeimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {......private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app) throws RemoteException {......r.app = app;......app.services.add(r);......try {......app.thread.scheduleCreateService(r, r.serviceInfo);......} finally {......}requestServiceBindingsLocked(r);......}...... }?? ? ? ?這個(gè)函數(shù)執(zhí)行了兩個(gè)操作,一個(gè)是操作是調(diào)用app.thread.scheduleCreateService函數(shù)來(lái)在應(yīng)用程序進(jìn)程內(nèi)部啟動(dòng)CounterService,這個(gè)操作會(huì)導(dǎo)致CounterService的onCreate函數(shù)被調(diào)用;另一個(gè)操作是調(diào)用requestServiceBindingsLocked函數(shù)來(lái)向CounterService要一個(gè)Binder對(duì)象,這個(gè)操作會(huì)導(dǎo)致CounterService的onBind函數(shù)被調(diào)用。?? ? ? ?這里,我們先沿著app.thread.scheduleCreateService這個(gè)路徑分析下去,然后再回過(guò)頭來(lái)分析requestServiceBindingsLocked的調(diào)用過(guò)程。這里的app.thread是一個(gè)Binder對(duì)象的遠(yuǎn)程接口,類(lèi)型為ApplicationThreadProxy。每一個(gè)Android應(yīng)用程序進(jìn)程里面都有一個(gè)ActivtyThread對(duì)象和一個(gè)ApplicationThread對(duì)象,其中是ApplicationThread對(duì)象是ActivityThread對(duì)象的一個(gè)成員變量,是ActivityThread與ActivityManagerService之間用來(lái)執(zhí)行進(jìn)程間通信的,具體可以參考Android應(yīng)用程序啟動(dòng)過(guò)程源代碼分析一文。
?? ? ? ?Step 9. ApplicationThreadProxy.scheduleCreateService
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
?? ? ? ? Step 10.?ApplicationThread.scheduleCreateService
?? ? ? ??這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
?? ? ? ? Step 11.?ActivityThread.queueOrSendMessage
?? ? ? ??這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
?? ? ? ?Step 12. H.sendMessage
?? ? ? ?由于H類(lèi)繼承于Handler類(lèi),因此,這里實(shí)際執(zhí)行的Handler.sendMessage函數(shù),這個(gè)函數(shù)定義在frameworks/base/core/java/android/os/Handler.java文件,這里我們就不看了,有興趣的讀者可以自己研究一下,調(diào)用了這個(gè)函數(shù)之后,這個(gè)消息就真正地進(jìn)入到ActivityThread的消息隊(duì)列去了,最終這個(gè)消息由H.handleMessage函數(shù)來(lái)處理,這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
public final class ActivityThread {......private final class H extends Handler {......public void handleMessage(Message msg) {......switch (msg.what) {......case CREATE_SERVICE:handleCreateService((CreateServiceData)msg.obj);break;......}}}...... }?? ? ? ?這個(gè)消息最終由ActivityThread的handleCreateService函數(shù)來(lái)處理。?? ? ? ?Step 13.?ActivityThread.handleCreateService
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
?? ? ? ? 這個(gè)函數(shù)的工作就是把CounterService類(lèi)加載到內(nèi)存中來(lái),然后調(diào)用它的onCreate函數(shù)。
?? ? ? ? Step 14. CounterService.onCreate
?? ? ? ? 這個(gè)函數(shù)定義在Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃中一文中所介紹的應(yīng)用程序Broadcast的工程目錄下的src/shy/luo/broadcast/CounterService.java文件中:
public class CounterService extends Service implements ICounterService {......@Override public void onCreate() { super.onCreate(); Log.i(LOG_TAG, "Counter Service Created."); } ...... }?? ? ? ?這樣,CounterService就啟動(dòng)起來(lái)了。?? ? ? ?至此,應(yīng)用程序綁定服務(wù)過(guò)程中的第一步MainActivity.bindService->CounterService.onCreate就完成了。
?? ? ? ?這一步完成之后,我們還要回到Step ?8中去,執(zhí)行下一個(gè)操作,即調(diào)用ActivityManagerService.requestServiceBindingsLocked函數(shù),這個(gè)調(diào)用是用來(lái)執(zhí)行CounterService的onBind函數(shù)的。
?? ? ? ?Step 15.?ActivityManagerService.requestServiceBindingsLocked
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNativeimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {......private final void requestServiceBindingsLocked(ServiceRecord r) {Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();while (bindings.hasNext()) {IntentBindRecord i = bindings.next();if (!requestServiceBindingLocked(r, i, false)) {break;}}}private final boolean requestServiceBindingLocked(ServiceRecord r,IntentBindRecord i, boolean rebind) {......if ((!i.requested || rebind) && i.apps.size() > 0) {try {......r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);......} catch (RemoteException e) {......}}return true;}...... }?? ? ? ?這里的參數(shù)r就是我們?cè)谇懊娴腟tep 6中創(chuàng)建的ServiceRecord了,它代表剛才已經(jīng)啟動(dòng)了的CounterService。函數(shù)requestServiceBindingsLocked調(diào)用了requestServiceBindingLocked函數(shù)來(lái)處理綁定服務(wù)的操作,而函數(shù)requestServiceBindingLocked又調(diào)用了app.thread.scheduleBindService函數(shù)執(zhí)行操作,前面我們已經(jīng)介紹過(guò)app.thread,它是一個(gè)Binder對(duì)象的遠(yuǎn)程接口,類(lèi)型是ApplicationThreadProxy。?? ? ? ?Step 16.?ApplicationThreadProxy.scheduleBindService
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
class ApplicationThreadProxy implements IApplicationThread {......public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)throws RemoteException {Parcel data = Parcel.obtain();data.writeInterfaceToken(IApplicationThread.descriptor);data.writeStrongBinder(token);intent.writeToParcel(data, 0);data.writeInt(rebind ? 1 : 0);mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);data.recycle();}...... }?? ? ? ? 這里通過(guò)Binder驅(qū)動(dòng)程序就進(jìn)入到ApplicationThread的scheduleBindService函數(shù)去了。?? ? ? ? Step 17.?ApplicationThread.scheduleBindService
?? ? ? ??這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
?? ? ? ?Step 18.?ActivityThread.queueOrSendMessage
?? ? ? ?參考上面的Step 11,不過(guò)這里的消息類(lèi)型是H.BIND_SERVICE。
?? ? ? ?Step 19.?H.sendMessage
?? ? ? ?參考上面的Step 12,不過(guò)這里最終在H.handleMessage函數(shù)中,要處理的消息類(lèi)型是H.BIND_SERVICE:
public final class ActivityThread {......private final class H extends Handler {......public void handleMessage(Message msg) {......switch (msg.what) {......case BIND_SERVICE:handleBindService((BindServiceData)msg.obj);break;......}}}...... }?? ? ? ? 這里調(diào)用ActivityThread.handleBindService函數(shù)來(lái)進(jìn)一步處理。?? ? ? ? Step 20.?ActivityThread.handleBindService
?? ? ? ? 這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
?? ? ? ?我們先看CounterService.onBind操作,然后再回到ActivityThread.handleBindService函數(shù)中來(lái)。
?? ? ? ?Step 21. CounterService.onBind
?? ? ? ?這個(gè)函數(shù)定義在Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃中一文中所介紹的應(yīng)用程序Broadcast的工程目錄下的src/shy/luo/broadcast/CounterService.java文件中:
public class CounterService extends Service implements ICounterService {......private final IBinder binder = new CounterBinder(); public class CounterBinder extends Binder { public CounterService getService() { return CounterService.this; } } @Override public IBinder onBind(Intent intent) { return binder; } ...... }?? ? ? ?這里的onBind函數(shù)返回一個(gè)是CounterBinder類(lèi)型的Binder對(duì)象,它里面實(shí)現(xiàn)一個(gè)成員函數(shù)getService,用于返回CounterService接口。?? ? ? ?至此,應(yīng)用程序綁定服務(wù)過(guò)程中的第二步CounterService.onBind就完成了。
?? ? ? ?回到ActivityThread.handleBindService函數(shù)中,獲得了這個(gè)CounterBinder對(duì)象后,就調(diào)用ActivityManagerProxy.publishService來(lái)通知MainActivity,CounterService已經(jīng)連接好了。
?? ? ? ?Step 22.?ActivityManagerProxy.publishService
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
?? ? ? ? Step 23.?ActivityManagerService.publishService
?? ? ? ??這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNativeimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {......public void publishService(IBinder token, Intent intent, IBinder service) {......synchronized(this) {......ServiceRecord r = (ServiceRecord)token;............if (r != null) {Intent.FilterComparison filter= new Intent.FilterComparison(intent);IntentBindRecord b = r.bindings.get(filter);if (b != null && !b.received) {b.binder = service;b.requested = true;b.received = true;if (r.connections.size() > 0) {Iterator<ArrayList<ConnectionRecord>> it= r.connections.values().iterator();while (it.hasNext()) {ArrayList<ConnectionRecord> clist = it.next();for (int i=0; i<clist.size(); i++) {ConnectionRecord c = clist.get(i);......try {c.conn.connected(r.name, service);} catch (Exception e) {......}}}}}......}}}...... }?? ? ? ?這里傳進(jìn)來(lái)的參數(shù)token是一個(gè)ServiceRecord對(duì)象,它是在上面的Step 6中創(chuàng)建的,代表CounterService這個(gè)Service。在Step 6中,我們?cè)?jīng)把一個(gè)ConnectionRecord放在ServiceRecord.connections列表中: ServiceRecord s = res.record;......ConnectionRecord c = new ConnectionRecord(b, activity,connection, flags, clientLabel, clientIntent);IBinder binder = connection.asBinder();ArrayList<ConnectionRecord> clist = s.connections.get(binder);if (clist == null) {clist = new ArrayList<ConnectionRecord>();s.connections.put(binder, clist);}?? ? ? ?因此,這里可以從r.connections中將這個(gè)ConnectionRecord取出來(lái): Iterator<ArrayList<ConnectionRecord>> it= r.connections.values().iterator();while (it.hasNext()) {ArrayList<ConnectionRecord> clist = it.next();for (int i=0; i<clist.size(); i++) {ConnectionRecord c = clist.get(i);......try {c.conn.connected(r.name, service);} catch (Exception e) {......}}}?? ? ? ?每一個(gè)ConnectionRecord里面都有一個(gè)成員變量conn,它的類(lèi)型是IServiceConnection,是一個(gè)Binder對(duì)象的遠(yuǎn)程接口,這個(gè)Binder對(duì)象又是什么呢?這就是我們?cè)赟tep?4中創(chuàng)建的LoadedApk.ServiceDispatcher.InnerConnection對(duì)象了。因此,這里執(zhí)行c.conn.connected函數(shù)后就會(huì)進(jìn)入到LoadedApk.ServiceDispatcher.InnerConnection.connected函數(shù)中去了。
?? ? ? ?Step 24. InnerConnection.connected
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:
final class LoadedApk {......static final class ServiceDispatcher {......private static class InnerConnection extends IServiceConnection.Stub {......public void connected(ComponentName name, IBinder service) throws RemoteException {LoadedApk.ServiceDispatcher sd = mDispatcher.get();if (sd != null) {sd.connected(name, service);}}......}......}...... }?? ? ? ? 這里它將操作轉(zhuǎn)發(fā)給ServiceDispatcher.connected函數(shù)。?? ? ? ? Step 25.?ServiceDispatcher.connected
?? ? ? ??這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:
final class LoadedApk {......static final class ServiceDispatcher {......public void connected(ComponentName name, IBinder service) {if (mActivityThread != null) {mActivityThread.post(new RunConnection(name, service, 0));} else {......}}......}...... }?? ? ? ?我們?cè)谇懊鍿tep 4中說(shuō)到,這里的mActivityThread是一個(gè)Handler實(shí)例,它是通過(guò)ActivityThread.getHandler函數(shù)得到的,因此,調(diào)用它的post函數(shù)后,就會(huì)把一個(gè)消息放到ActivityThread的消息隊(duì)列中去了。?? ? ? ?Step 26. H.post
?? ? ? ?由于H類(lèi)繼承于Handler類(lèi),因此,這里實(shí)際執(zhí)行的Handler.post函數(shù),這個(gè)函數(shù)定義在frameworks/base/core/java/android/os/Handler.java文件,這里我們就不看了,有興趣的讀者可以自己研究一下,調(diào)用了這個(gè)函數(shù)之后,這個(gè)消息就真正地進(jìn)入到ActivityThread的消息隊(duì)列去了,與sendMessage把消息放在消息隊(duì)列不一樣的地方是,post方式發(fā)送的消息不是由這個(gè)Handler的handleMessage函數(shù)來(lái)處理的,而是由post的參數(shù)Runnable的run函數(shù)來(lái)處理的。這里傳給post的參數(shù)是一個(gè)RunConnection類(lèi)型的參數(shù),它繼承了Runnable類(lèi),因此,最終會(huì)調(diào)用RunConnection.run函數(shù)來(lái)處理這個(gè)消息。
?? ? ? Step 27.?RunConnection.run
?? ? ??這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:
final class LoadedApk {......static final class ServiceDispatcher {......private final class RunConnection implements Runnable {......public void run() {if (mCommand == 0) {doConnected(mName, mService);} else if (mCommand == 1) {......}}......}......}...... }?? ? ? ?這里的mCommand值為0,于是就執(zhí)行ServiceDispatcher.doConnected函數(shù)來(lái)進(jìn)一步操作了。?? ? ? ?Step 28.?ServiceDispatcher.doConnected
?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:
?? ? ? ?Step 29. ServiceConnection.onServiceConnected
?? ? ? ?這個(gè)函數(shù)定義在Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃中一文中所介紹的應(yīng)用程序Broadcast的工程目錄下的src/shy/luo/broadcast/MainActivity.java文件中:
public class MainActivity extends Activity implements OnClickListener { ......private ServiceConnection serviceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { counterService = ((CounterService.CounterBinder)service).getService(); Log.i(LOG_TAG, "Counter Service Connected"); } ......}; ...... }?? ? ? ?這里傳進(jìn)來(lái)的參數(shù)service是一個(gè)Binder對(duì)象,就是前面在Step 21中從CounterService那里得到的ConterBinder對(duì)象,因此,這里可以把它強(qiáng)制轉(zhuǎn)換為CounterBinder引用,然后調(diào)用它的getService函數(shù)。?? ? ? ?至此,應(yīng)用程序綁定服務(wù)過(guò)程中的第三步MainActivity.ServiceConnection.onServiceConnection就完成了。
?? ? ? ?Step 30. CounterBinder.getService
?? ? ? ?這個(gè)函數(shù)定義在Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃中一文中所介紹的應(yīng)用程序Broadcast的工程目錄下的src/shy/luo/broadcast/CounterService.java文件中:
public class CounterService extends Service implements ICounterService { ......public class CounterBinder extends Binder { public CounterService getService() { return CounterService.this; } } ...... }?? ? ? ?這里就把CounterService接口返回給MainActivity了。?? ? ? ?至此,應(yīng)用程序綁定服務(wù)過(guò)程中的第四步CounterService.CounterBinder.getService就完成了。
?? ? ? ?這樣,Android應(yīng)用程序綁定服務(wù)(bindService)的過(guò)程的源代碼分析就完成了,總結(jié)一下這個(gè)過(guò)程:
?? ? ? ?1. Step 1 - ?Step 14,MainActivity調(diào)用bindService函數(shù)通知ActivityManagerService,它要啟動(dòng)CounterService這個(gè)服務(wù),ActivityManagerService于是在MainActivity所在的進(jìn)程內(nèi)部把CounterService啟動(dòng)起來(lái),并且調(diào)用它的onCreate函數(shù);
?? ? ? ?2. Step 15 - Step 21,ActivityManagerService把CounterService啟動(dòng)起來(lái)后,繼續(xù)調(diào)用CounterService的onBind函數(shù),要求CounterService返回一個(gè)Binder對(duì)象給它;
?? ? ? ?3. Step 22 - Step 29,ActivityManagerService從CounterService處得到這個(gè)Binder對(duì)象后,就把它傳給MainActivity,即把這個(gè)Binder對(duì)象作為參數(shù)傳遞給MainActivity內(nèi)部定義的ServiceConnection對(duì)象的onServiceConnected函數(shù);
?? ? ? ?4. Step 30,MainActivity內(nèi)部定義的ServiceConnection對(duì)象的onServiceConnected函數(shù)在得到這個(gè)Binder對(duì)象后,就通過(guò)它的getService成同函數(shù)獲得CounterService接口。
老羅的新浪微博:http://weibo.com/shengyangluo,歡迎關(guān)注!
轉(zhuǎn)載于:https://www.cnblogs.com/wuyida/archive/2011/09/07/6300563.html
總結(jié)
以上是生活随笔為你收集整理的Android应用程序绑定服务(bindService)的过程源代码分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 陈劲晒moto razr 2022真机:
- 下一篇: 不止CPU 龙芯进军汽车芯片:首款MCU