【Android源码 栏目提醒】:以下是网学会员为您推荐的Android源码 -Android应用程序绑定服务(bindService)的过程源代码分析 - 开发文档,希望本篇文章对您学习有所帮助。
Android应用程序组件Service与Activity一样,既可以在新的进程中启动,也可以在应用程序进程内部启动;前面我们已经分析了在新的进程中启动Service的过程,本文将要介绍在应用程序内部绑定Service的过程,这是一种在应用程序进程内部启动Service的方法。
在前面一篇文章
Android进程间通信(IPC)机制Binder简要介绍和学习计划中,我们就曾经提到,在
Android系统中,每一个应用程序都是由一些Activity和Service组成的,一般Service运行在独立的进程中,而Activity有可能运行在同一个进程中,也有可能运行在不同的进程中;在接下来的文章中,
Android系统在新进程中启动自定义服务过程(startService)的原理分析一文介绍了在新的进程中启动Service的过程,
Android应用程序启动过程源代码分析一文介绍了在新的进程中启动Activity的过程,而
Android应用程序内部启动Activity过程(startActivity)的源代码分析一文则介绍了在应用程序进程内部启动Activity的过程;本文接过最后一棒,继续介绍在应用程序进程内部启动Service的过程,这种过程又可以称在应用程序进程内部绑定服务(bindService)的过程,这样,读者应该就可以对
Android应用程序启动Activity和Service有一个充分的认识了。
这里仍然是按照老规矩,通过具体的例子来分析
Android应用程序绑定Service的过程,而所使用的例子便是前面我们在介绍
Android系统广播机制的一篇文章
Android系统中的广播(Broadcast)机制简要介绍和学习计划中所开发的应用程序Broadcast了。
我们先简单回顾一下这个应用程序实例绑定Service的过程。
在这个应用程序的MainActivity的onCreate函数中,会调用bindService来绑定一个计数器服务CounterService,这里绑定的意思其实就是在MainActivity内部获得CounterService的接口,所以,这个过程的第一步就是要把CounterService启动起来。
当CounterService的onCreate函数被调用起来了,就说明CounterService已经启动起来了,接下来系统还要调用CounterService的onBind函数,跟CounterService要一个Binder对象,这个Binder对象是在CounterService内部自定义的CounterBinder类的一个实例,它继承于Binder类,里面实现一个getService函数,用来返回外部的CounterService接口。
系统得到这个Binder对象之后,就会调用MainActivity在bindService函数里面传过来的ServiceConnection实例的onServiceConnected函数,并把这个Binder对象以参数的形式传到onServiceConnected函数里面,于是,MainActivity就可以调用这个Binder对象的getService函数来获得CounterService的接口了。
这个过程比较复杂,但总体来说,思路还是比较清晰的,整个调用过程为MainActivity.bindService-gtCounterService.onCreate-gtCounterService.onBind-gtMainActivity.ServiceConnection.onServiceConnection-gtCounterService.CounterBinder.getService。
下面,我们就先用一个序列图来总体描述这个服务绑定的过程,然后就具体分析每一个步骤。
点击查看大图 Step 1. ContextWrapper.bindService 无法加载插件。
这个函数定义在frameworks/base/core/java/
android/content/ContextWrapper.java文件中: java 10. ulc ls otxWapr xed otx pbi casCnetrpe etnsCnet 20. otx Bs Cnetmae 30. ... ... 40. 50. Oerd vrie 60. ulc ola idevcnet evc evcCneto on pbi boenbnSrieItn srie Srieoncincn 70. n lg itfas 80. eun Bs.idevcevc on lg rtr maebnSriesrie cnfas 90. 01. 11. ... ... 21. 这里的mBase是一个ContextImpl实例变量,于是就调用ContextImpl的bindService函数来进一步处理。
Step 2. ContextImpl.bindService . 无法加载插件。
这个函数定义在frameworks/base/core/java/
android/app/ContextImpl.java文件中: java 1 0. ls otxIp xed otx casCnetmletnsCnet 2 0. ... ... 3 0. 4 0. Oerd vrie 5 0. ulc ola idevcnet evc evcCneto on pbi boenbnSrieItn srie Srieoncincn 6 0. n lg itfas 7 0. Srieoncin d IevcCneto s 8 0. f makgIf ul i Pcaeno nl 9 0. d PcaenogtevcDsaceon eOtrotx s makgIf.eSrieipthrcngtueCnet 0 1. MiTra.eHnlr lg manhedgtadefas 1 1. le es 2 1. ... ... 3 1. 4 1. r ty 5 1. n e ciiyaaeNtv.eDfutbnSrie itrsAtvtMngraiegteal.idevc 6 1. MiTra.eApiainhed eAtvtTkn manhedgtplctoTragtciiyoe 7 1. evc evc.eovTpINeeeCneteovr srie sriersleyefeddgtotnRsle 8 1. d lg sfas 9 1. ... ... 0 2. eun e rtr rs 0 1 2. ac RmtEcpin ctheoexeto e 2 2. eun as rtr fle 3 2. 4 2. 5 2. 6 2. ... ... 7 2. 8 2. 这里的mMainThread是一个ActivityThread实例,通过它的getHandler函数可以获得一个Handler对象,有了这个Handler对象后,就可以把消息分发到ActivityThread所在的线程消息队列中去了,后面我们将会看到这个用法,现在我们暂时不关注,只要知道这里从ActivityThread处获得了一个Handler并且保存在下面要介绍的ServiceDispatcher中去就可以了。
我们先看一下ActivityThread.getHandler的实现,然后再回到这里的bindService函数来。
Step 3. ActivityThread.getHandler 这个函数定义在frameworks/base/core/java/
android/app/ActivityThread.java文件中: 无法加载插件。
java 1 0. ulc ia ls ciiyhed pbi fnlcasAtvtTra 2 0. ... ... 3 0. 4 0. ia H e fnlHm nwH 5 0. 6 0. ... ... 7 0. 8 0. rvt ia ls xed ade piaefnlcasHetnsHnlr 9 0. ... ... 0 1. 1 1. ulc od adeesgesg s pbi vi hnlMsaeMsaemg 2 1. ... ... 3 1. 4 1. 5 1. ... ... 6 1. 7 1. 8 1. ... ... 9 1. 0 2. ia ade eHnlr fnlHnlrgtade 1 2. eun H rtr m 2 2. 3 2. 4 2. ... ... 5 2. 这里返回的Handler是在ActivityThread类内部从Handler类继承下来的一个H类实例变量。
回到Step 2中的ContextImpl.bindService函数中,获得了这个Handler对象后,就调用mPackageInfo.getServiceDispatcher函数来获得一个IServiceConnection接口,这里的mPackageInfo的类型是LoadedApk,我们来看看它的getServiceDispatcher函数的实现,然后再回到ContextImpl.bindService函数来。
Step 4. LoadedApk.getServiceDispatcher 无法加载插件。
这个函数定义在frameworks/base/core/java/
android/app/LoadedApk.java文件中: java 1 0. ia ls oddp fnlcasLaeAk 2 0. ... ... 3 0. 4 0. ulc ia Srieoncin eSrieipthrSrieoncin pbi fnlIevcCneto gtevcDsaceevcCneto c 5 0. otx otx ade ade n lg Cnetcnet Hnlrhnlr itfas 6 0. ycrnzd mevcs snhoie Srie 7 0. oddp.evcDsace d ul LaeAkSrieipthrs nl 8 0. ahaltevcCneto oddp.evcDsacegt a Srie.eotx HsMpSrieoncin LaeAkSrieipthr mpmevcsgtcnet 9 0. f mp ul i a nl 0 1. d a.e s mpgtc 1 1. 2 1. f s ul i d nl 3 1. d e evcDsace otx ade lg s nwSrieipthrc cnet hnlr fas 4 1. f mp ul i a nl 5 1. a e ahaltevcCneto oddp.evcDsacegt mpnwHsMpSrieoncin LaeAkSrieipthr 6 1. Srie.uotx a mevcsptcnet mp 7 1. 8 1. a.u d mpptc s 9 1. le es 0 2. dvldtotx ade s.aiaecnet hnlr 1 2. 2 2. eun dgtSrieoncin rtr s.eIevcCneto 3 2. 4 2. 5 2. 6 2. ... ... 7 2. 8 2. ttc ia ls evcDsace sai fnlcasSrieipthr 9 2. rvt ia evcDsace.neCneto IevcCneto piaefnlSrieipthrInroncinmSrieoncin 0 3. rvt ia evcCneto Cneto piaefnlSrieoncinmoncin 1 3. rvt ia ade AtvtTra piaefnlHnlrmciiyhed 2 3. ... ... 3 3. 4 3. rvt ttc ls neCneto xed SrieoncinSu piaesai casInroncinetnsIevcCneto.tb 5 3. ia ekeeecltoddp.evcDsacegt Dsace fnlWaRfrneLaeAkSrieipthr mipthr 6 3. ... ... 7 3. 8 3. neCnetooddp.evcDsace d InroncinLaeAkSrieipthrs 9 3. Dsace e ekeeecltoddp.evcDsacegts mipthrnwWaRfrneLaeAkSrieipthrd 0 4. 1 4. 2 4. ... ... 3 4. 4 4. 5 4. ... ... 6 4. 7 4. evcDsaceevcCneto on SrieipthrSrieoncincn 8 4. otx otx ade ciiyhed n lg Cnetcnet HnlratvtTraitfas 9 4. IevcCneto e neCnetohs mSrieoncinnwInroncinti 0 5. Cneto on moncincn 1 5. AtvtTra ciiyhed mciiyhedatvtTra 2 5. ... ... 3 5. 4 5. 5 5. ... ... 6 5. 7 5. Srieoncin eIevcCneto IevcCneto gtSrieoncin 8 5. eun IevcCneto rtr mSrieoncin 9 5. 0 6. 1 6. ... ... 2 6. 3 6. 4 6. ... ... 5 6. 在getServiceDispatcher函数中,传进来的参数context是一个MainActivity实例,先以它为Key值在mServices中查看一下,是不是已经存在相应的ServiceDispatcher实例,如果有了,就不用创建了,直接取出来。
在我们这个情景中,需要创建一个新的ServiceDispatcher。
在创建新的ServiceDispatcher实例的过程中,将上面传下来ServiceConnection参数c和Hanlder参数保存在了ServiceDispatcher实例的内部,并且创建了一个InnerConnection对象,这是一个Binder对象,一会是要传递给ActivityManagerService的,ActivityManagerServic后续就是要通过这个Binder对象和ServiceConnection通信的。
函数getServiceDispatcher最后就是返回了一个InnerConnection对象给ContextImpl.bindService函数。
回到ContextImpl.bindService函数中,它接着就要调用ActivityManagerService的远程接口来进一步处理了。
Step 5. ActivityManagerService.bindService 这个函数定义在frameworks/base/core/java/
android/app/ActivityManagerNative.java文件中: 无法加载插件。
java 1 0. ls ciiyaaePoy mlmns AtvtMngr casAtvtMngrrx ipeet Iciiyaae 2 0. 3 0. ... ... 4 0. 5 0. ulc n idevcApiainhed alr Bne oe pbi itbnSrieIplctoTra cleIidrtkn 6 0. net evc tig eovdye Srieoncin oncin Itn srie Srn rsleTpIevcCneto cneto 7 0. n lg hos eoexeto itfas trw RmtEcpin 8 0. acl aa acloti Pre dt Pre.ban 9 0. acl el acloti Pre rpyPre.ban 0 1. aawienefcTknIciiyaae.ecitr dt.rtItraeoeAtvtMngrdsrpo 1 1. aawietogidrcle ul alraBne ul dt.rtSrnBnealr nl cle.sidr:nl 2 1. aawietogidrtkn dt.rtSrnBneoe 3 1. evc.rtTPreaa sriewieoacldt0 4 1. aawietigrsleTp dt.rtSrneovdye 5 1. aawietogidrcneto.sidr dt.rtSrnBneoncinaBne 6 1. aawienlg dt.rtItfas 7 1. Rmt.rnatBN_EVC_RNATO aa el meoetascIDSRIETASCIN dtrpy 0 8 1. el.edxeto rpyraEcpin 9 1. n e el.edn itrsrpyraIt 0 2. aarcce dt.eyl 1 2. el.eyl rpyrcce 2 2. eun e rtr rs 3 2. 4 2. 5 2. ... ... 6 2. 这个函数通过Binder驱动程序就进入到ActivityManagerService的bindService函数去了。
Step 6. ActivityManagerService.bindService 这个函数定义在frameworks/base/services/java/com/
android/server/am/ActivityManagerService.java文件中: 无法加载插件。
java 10. ulc ia ls ciiyaaeSrie xed ciiyaaeNtv pbi fnlcasAtvtMngrevc etnsAtvtMngraie 20. mlmns acdgMntr atrSasmlBteyalak ipeet Wtho.oioBteyttIp.atrClbc 30. ... ... 40. 50. ulc n idevcApiainhed alr Bne oe pbi itbnSrieIplctoTra cleIidrtkn 60. net evc tig eovdye Itn srie Srn rsleTp 70. Srieoncin oncin n lg IevcCneto cnetoitfas 80. ... ... 90. 01. ycrnzdti snhoiehs 11. ... ... 21. ia rcsRcr alrp eRcrFrpLcealr fnlPoeseodcleApgteodoApokdcle 31. ... ... 41. 51. ciiyeod ciiy ul AtvtRcr atvt nl 61. f tkn ul i oe nl 71. n idx MiSakidxfoeLceoe itane mantc.neOTknokdtkn 81. ... ... 91. ciiy AtvtRcrMiSakmitr.eidx atvt ciiyeodmantc.Hsoygtane 02. 12. 22. ... ... 32. 42. evcLouRsl e Srieokpeutrs 52. ereeevcLceevc eovdye rtivSrieokdsrie rsleTp 62. idrgtalnPd idrgtalnUd Bne.eCligiBne.eCligi 72. 82. ... ... 92. 03. evcRcr e.eod Srieeodsrsrcr 13. 23. ia og rgd idrceralnIett fnlln oiI Bne.laCligdniy 33. 43. ... ... 53. 63. pBnRcr .ereepBnigokdsrie alrp ApideodbsrtivApidnLceevccleAp 73. oncineod e oncineodb ciiy CnetoRcr cnwCnetoRcratvt 83. oncin lg letae letnet cnetofas cinLbl cinItn 93. 04. Bne idr oncinaBne Iidrbne cneto.sidr 14. raLsltoncineod ls .oncin.eidr AryitCnetoRcrgtcitscnetosgtbne 24. 34. f cit ul i ls nl 44. ls e raLsltoncineod citnwAryitCnetoRcrgt 54. .oncin.uidr ls scnetosptbnecit 64. 74. ls.d citadc 84. .oncin.d bcnetosadc 94. f atvt ul .
上一篇:
Android应用程序绑定服务(bindService)的过程源代码分析
下一篇:
网络能耗监测系统管理端的研究与实现