《Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码nfz.docx》由会员分享,可在线阅读,更多相关《Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码nfz.docx(73页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、 在在前面几几篇文章章中,我我们详细细介绍了了Anddroiid系统统进程间间通信机机制Biindeer的原原理,并并且深入入分析了了系统提提供的BBindder运运行库和和驱动程程序的源源代码。细细心的读读者会发发现,这这几篇文文章分析析的Biindeer接口口都是基基于C/C+语言来来实现的的,但是是我们在在编写应应用程序序都是基基于Jaava语语言的,那那么,我我们如何何使用JJavaa语言来来使用系系统的BBindder机机制来进进行进程程间通信信呢?这这就是本本文要介介绍的AAndrroidd系统应应用程序序框架层层的用JJavaa语言来来实现的的Binnderr接口了了。 熟悉An
2、ndrooid系系统的读读者,应应该能想想到应用用程序框框架中的的基于JJavaa语言的的Binnderr接口是是通过JJNI来来调用基基于C/C+语言的的Binnderr运行库库来为JJavaa应用程程序提供供进程间间通信服服务的了了。JNNI在Anddroiid系统统中用得得相当普普遍,SSDK中中的Jaava接接口APPI很多多只是简简单地通通过JNNI来调调用底层层的C/C+运行库库从而为为应用程程序服务务的。 这里,我我们仍然然是通过过具体的的例子来来说明BBindder机机制在应应用程序序框架层层中的JJavaa接口,主主要就是是Serrvicce MManaagerr、Serrv
3、err和Cliientt这三个个角色的的实现了了。通常常,在应应用程序序中,我我们都是是把Seerveer实现现为Seerviice的的形式,并并且通过过ISeerviiceMManaagerr.adddSeerviice接接口来把把这个SServvicee添加到到Serrvicce MManaagerr,Cliientt也是通通过ISServviceeMannageer.ggetSServvicee接口来来获得SServvicee接口,接接着就可可以使用用这个SServvicee提供的的功能了了,这个个与运行行时库的的Binnderr接口是是一致的的。 前面我我们学习习Anddroiid硬件
4、件抽象层层时,曾曾经在应应用程序序框架层层中提供供了一个个硬件访访问服务务HellloSServvicee,这个个Serrvicce运行行在一个个独立的的进程中中充当SServver的的角色,使使用这个个Serrvicce的Cliientt运行在在另一个个进程中中,它们们之间就就是通过过Binnderr机制来来通信的的了。这这里,我我们就使使用HeellooSerrvicce这个个例子来来分析AAndrroidd系统进进程间通通信Biindeer机制制在应用用程序框框架层的的Javva接口口源代码码。所以以希望读读者在阅阅读下面面的内容容之前,先先了解一一下前面面在Ubuuntuu上为Annd
5、rooid系系统的AAppllicaatioon FFrammewoorkss层增加加硬件访访问服务务这篇文文章。 这篇文文章通过过五个情情景来学学习Anndrooid系系统进程程间通信信Binnderr机制在在应用程程序框架架层的JJavaa接口:1. 获取Seerviice Mannageer的Javva远程程接口的的过程;2. HellloSServvicee接口的的定义;3. HellloSServvicee的启动动过程;4. Cliientt获取HeellooSerrvicce的Javva远程程接口的的过程;5.Clliennt通过过HellloSServvicee的Javva远程程
6、接口来来使用HHellloSeerviice提提供的服服务的过过程。 一. 获取Seerviice Mannageer的Javva远程程接口 我们要要获取的的Serrvicce MManaagerr的Javva远程程接口是是一个SServviceeMannageerPrroxyy对象的的ISeerviiceMManaagerr接口。我我们现在在就来看看看SeerviiceMManaagerrProoxy类类是长什什么样子子的: 这这里可以以看出,ServiceManagerProxy类实现了IServiceManager接口,IServiceManager提供了getService和addSe
7、rvice两个成员函数来管理系统中的Service。从ServiceManagerProxy类的构造函数可以看出,它需要一个BinderProxy对象的IBinder接口来作为参数。因此,要获取Service Manager的Java远程接口ServiceManagerProxy,首先要有一个BinderProxy对象。下面将会看到这个BinderProxy对象是如何获得的。 再再来看一一下是通通过什么么路径来来获取SServvicee Maanagger的的Javva远程程接口SServviceeMannageerPrroxyy的。这这个主角角就是SServviceeMannageer了,我
8、我们也先先看一下下SerrvicceMaanagger是是长什么么样子的的: SeerviiceMManaagerr类有一一个静态态成员函函数geetISServviceeMannageer,它它的作用用就是用用来获取取Serrvicce MManaagerr的Javva远程程接口了了,而这这个函数数又是通通过SeerviiceMManaagerrNattivee来获取取Serrvicce MManaagerr的Javva远程程接口的的。 接下下来,我我们就看看一下SServviceeMannageer.ggetIISerrvicceMaanagger这这个函数数的实现现,这个个函数定定义在f
9、frammewoorkss/baase/corre/jjavaa/anndrooid/os/SerrvicceMaanagger.javva文件件中:vieww pllainn1. publlicfinnalclaassSerrvicceMaanagger2. .3. priivattestaaticcISServviceeMannageerssSerrvicceMaanagger;4. .5. priivattestaaticcISServviceeMannageerggetIISerrvicceMaanagger()6. iff(ssSerrvicceMaanagger!=nulll)7.
10、 rretuurnsSeerviiceMManaagerr;8. 9. 10. /Fiindtheeseerviicemannageer11. sSServviceeMannageer=SeerviiceMManaagerrNattivee.assIntterffacee(BiindeerInnterrnall.geetCoonteextOObjeect();12. reeturrnssSerrvicceMaanagger;13. 14. .15. 如果果其静态态成员变变量sSServviceeMannageer尚未未创建,那那么就调调用SeerviiceMManaagerrNattivee.
11、assIntterffacee函数来来创建。在在调用SServviceeMannageerNaativve.aasInnterrfacce函数数之前,首首先要通通过BiindeerInnterrnall.geetCoonteextOObjeect函函数来获获得一个个BinnderrProoxy对对象。 我们们来看一一下BiindeerInnterrnall.geetCoonteextOObjeect的的实现,这这个函数数定义在在fraamewworkks/bbasee/coore/javva/ccom/anddroiid/iinteernaal/oos/BBindderIInteernaal.
12、jjavaa文件中中:vieww pllainn1. publlicclaassBinnderrIntternnal2. .3. /*4. *RRetuurntheegllobaalconntexxtoobjeectoffthhessysttem.TThississussuallly5. *aaniimpllemeentaatioonoofIISerrvicceMaanagger,whhichhyoouccanuseetoofiind6. *ootheersservvicees.7. */8. pubbliccstaaticcfinnalnattiveeIBBinddergettConntex
13、xtObbjecct();9. 10. .11. 这里里可以看看出,BBindderIInteernaal.ggetCConttexttObjjectt是一个个JNII方法,它它实现在在fraamewworkks/bbasee/coore/jnii/anndrooid_utiil_BBindder.cppp文件中中:vieww pllainn1. statticjobbjecctaandrroidd_oss_BiindeerInnterrnall_geetCoonteextOObjeect(JNIIEnvv*eenv,joobjeectclaazz)2. 3. spb=PrroceessSSt
14、atte:sellf()-ggetCConttexttObjjectt(NUULL);4. retturnnjaavaOObjeectFForIIBinnderr(ennv,b);5. 这里看看到我们们熟悉的的ProocesssSttatee:sselff()-geetCoonteextOObjeect函函数,具具体可以以参考浅浅谈Anndrooid系系统进程程间通信信(IPPC)机机制Biindeer中的的Serrverr和Cliientt获得Seerviice Mannageer接口口之路一一文。PProccesssStaate:seelf()-gettConntexxtObbjecct函
15、数数返回一一个BppBinnderr对象,它它的句柄柄值是00,即下下面语句句:vieww pllainn1. spbb=ProocesssSttatee:sselff()-geetCoonteextOObjeect(NULLL); 相当于于是:vieww pllainn1. spbb=newwBppBinnderr(0); 接着调调用jaavaOObjeectFForIIBinnderr把这个个BpBBindder对对象转换换成一个个BinnderrProoxy对对象:vieww pllainn1. jobjjecttjaavaOObjeectFForIIBinnderr(JNNIEnnv*
16、envv,cconsstssp&vall)2. 3. if(vall=NUULL)reeturrnNNULLL;4. 5. if(vall-cchecckSuubcllasss(&ggBinnderrOfffsetts)6. /Onneoofoourownn!7. joobjeectobjjectt=staaticc_caast(vval.gett()-oobjeect();8. /priintff(oobjeectFForBBindder%p:ittsourrowwn%p!n,vaal.gget(),objjectt);9. reeturrnoobjeect;10. 11. 12. /For
17、rthherresttoffthheffuncctioonwwewwilllhooldthiisllockk,ttosseriialiize13. /loookinng/ccreaatioonoofJJavaaprroxiiesforrnaativveBBindderprooxiees.14. AuttoMuutexx_ll(mPProxxyLoock);15. 16. /Sommeonneeelsees.dooweeknnowabooutit?17. jobbjecctoobjeect=(jobbjecct)vval-fiindOObjeect(&gBBindderPProxxyOfffse
18、ets);18. if(objjectt!=NUULL)19. joobjeectress=envv-CCalllObjjecttMetthodd(obbjecct,gWeeakRRefeerennceOOffssetss.mGGet);20. iff(rres!=NULLL)21. LLOGVV(oobjeectFForBBindder%p:foounddexxisttingg%pp!nn,vall.geet(),rres);22. rretuurnress;23. 24. LOOGV(Prroxyyobbjecct%poofIIBinnderr%ppnooloongeeriinwworkk
19、inggseet!,obbjecct,vall.geet();25. anndrooid_atoomicc_deec(&gNuumPrroxyyReffs);26. vaal-dettachhObjjectt(&ggBinnderrProoxyOOffssetss);27. ennv-DelleteeGlooballReff(obbjecct);28. 29. 30. objjectt=envv-NNewOObjeect(gBiindeerPrroxyyOfffsetts.mmClaass,gBBindderPProxxyOfffseets.mCoonsttrucctorr);31. if(o
20、bjjectt!=NUULL)32. LOOGV(obbjecctFoorBiindeer%p:creeateednnew%p!n,vval.gett(),obbjecct);33. /Thhepproxxyhholddsaareeferrenccettotthenattiveeobbjecct.34. ennv-SettInttFieeld(objjectt,ggBinnderrProoxyOOffssetss.mOObjeect,(iint)vall.geet();35. vaal-inccStrrongg(obbjecct);36. 37. /Thhennatiiveobjjecttne
21、eedsstoohooldawweakkreeferrenccebbackktoothhe38. /prroxyy,ssowweccanrettrieevetheesaameprooxyifitisstiillacttivee.39. joobjeectreffObjjectt=envv-NNewGGlobbalRRef(40. envv-GGetOObjeectFFielld(oobjeect,gBBindderPProxxyOfffseets.mSeelf);41. vaal-atttachhObjjectt(&ggBinnderrProoxyOOffssetss,rrefOObjeect
22、,42. jniienvv_too_jaavavvm(eenv),pproxxy_ccleaanupp);43. 44. /Nootethaataaneewoobjeectreffereenceehaasbbeenncrreatted.45. anndrooid_atoomicc_innc(&gNuumPrroxyyReffs);46. inncReefsCCreaatedd(ennv);47. 48. 49. retturnnobbjecct;50. 在介介绍这个个函数之之前,先先来看两两个变量量gBiindeerOfffseets和和gBiindeerPrroxyyOfffsetts的定定
23、义。 先看看gBiindeerOfffseets的的定义:vieww pllainn1. statticstrructtbiindeernaativve_ooffssetss_t2. 3. /Claassstaate.4. jcllasssmCClasss;5. jmeethoodIDDmEExeccTraansaact;6. 7. /Objjecttsttatee.8. jfiielddIDmObbjecct;9. 10. gBBindderOOffssetss; 简单来来说,ggBinnderrOfffsetts变量量是用来来记录上上面第二二个类图图中的BBindder类类的相关关信息的的
24、,它是是在注册册Binnderr类的JNNI方法法的innt_rregiisteer_aandrroidd_oss_Biindeer函数数初始化化的:vieww pllainn1. consstchaar*connstkBiindeerPaathNNamee=anndrooid/os/Binnderr;2. 3. statticinttinnt_rregiisteer_aandrroidd_oss_Biindeer(JJNIEEnv*ennv)4. 5. jcllassscllazzz;6. 7. claazz=eenv-FiindCClasss(kkBinnderrPatthNaame);8
25、. LOGG_FAATALL_IFF(cllazzz=NUULL,UUnabbletofinndcclasssaandrroidd.oss.Biindeer);9. 10. gBiindeerOfffseets.mCllasss=(jcclasss)envv-NNewGGlobbalRRef(claazz);11. gBiindeerOfffseets.mExxecTTrannsacct12. =envv-GGetMMethhodIID(cclazzz,exxecTTrannsacct,(IIIII)ZZ);13. asssertt(gBBindderOOffssetss.mEExeccTra
26、ansaact);14. 15. gBiindeerOfffseets.mObbjecct16. =envv-GGetFFielldIDD(cllazzz,mObbjecct,II);17. asssertt(gBBindderOOffssetss.mOObjeect);18. 19. retturnnAnndrooidRRunttimee:rregiisteerNaativveMeethoods(20. ennv,kBiindeerPaathNNamee,21. gBBindderMMethhodss,NNELEEM(ggBinnderrMetthodds);22. 再来看看gBiindee
27、rPrroxyyOfffsetts的定定义:vieww pllainn1. statticstrructtbiindeerprroxyy_offfseets_t2. 3. /Claassstaate.4. jcllasssmCClasss;5. jmeethoodIDDmCConsstruuctoor;6. jmeethoodIDDmSSenddDeaathNNotiice;7. 8. /Objjecttsttatee.9. jfiielddIDmObbjecct;10. jfiielddIDmSeelf;11. 12. gBBindderPProxxyOfffseets; 简单来来说,ggB
28、innderrProoxyOOffssetss是用来来变量是是用来记记录上面面第一个个图中的的BinnderrProoxy类类的相关关信息的的,它是是在注册册BinnderrProoxy类类的JNNI方法法的innt_rregiisteer_aandrroidd_oss_BiindeerPrroxyy函数初初始化的的:vieww pllainn1. consstchaar*connstkBiindeerPrroxyyPatthNaame=anddroiid/oos/BBindderPProxxy;2. 3. statticinttinnt_rregiisteer_aandrroidd_oss_
29、BiindeerPrroxyy(JNNIEnnv*envv)4. 5. jcllassscllazzz;6. 7. claazz=eenv-FiindCClasss(javva/llangg/reef/WWeakkReffereencee);8. LOGG_FAATALL_IFF(cllazzz=NUULL,UUnabbletofinndcclasssjjavaa.laang.reff.WeeakRRefeerennce);9. gWeeakRRefeerennceOOffssetss.mCClasss=(jjclaass)ennv-NewwGlooballReff(cllazzz);10.
30、gWeeakRRefeerennceOOffssetss.mGGet11. =envv-GGetMMethhodIID(cclazzz,geet,()Ljjavaa/laang/Objjectt;);12. asssertt(gWWeakkReffereenceeOfffsetts.mmGett);13. 14. claazz=eenv-FiindCClasss(javva/llangg/Errrorr);15. LOGG_FAATALL_IFF(cllazzz=NUULL,UUnabbletofinndcclasssjjavaa.laang.Errror);16. gErrrorrOfffs
31、etts.mmClaass=(jcllasss)eenv-NeewGllobaalReef(cclazzz);17. 18. claazz=eenv-FiindCClasss(kkBinnderrProoxyPPathhNamme);19. LOGG_FAATALL_IFF(cllazzz=NUULL,UUnabbletofinndcclasssaandrroidd.oss.BiindeerPrroxyy);20. 21. gBiindeerPrroxyyOfffsetts.mmClaass=(jcllasss)eenv-NeewGllobaalReef(cclazzz);22. gBiind
32、eerPrroxyyOfffsetts.mmConnstrructtor23. =envv-GGetMMethhodIID(cclazzz,()V);24. asssertt(gBBindderPProxxyOfffseets.mCoonsttrucctorr);25. gBiindeerPrroxyyOfffsetts.mmSenndDeeathhNotticee26. =envv-GGetSStatticMMethhodIID(cclazzz,seendDDeatthNooticce,(Lanndrooid/os/IBiindeer$DDeatthReecippiennt;)V);27.
33、asssertt(gBBindderPProxxyOfffseets.mSeendDDeatthNooticce);28. 29. gBiindeerPrroxyyOfffsetts.mmObjjectt30. =envv-GGetFFielldIDD(cllazzz,mObbjecct,II);31. asssertt(gBBindderPProxxyOfffseets.mObbjecct);32. gBiindeerPrroxyyOfffsetts.mmSellf33. =envv-GGetFFielldIDD(cllazzz,mSeelf,LLjavva/llangg/reef/WWea
34、kkReffereencee;);34. asssertt(gBBindderPProxxyOfffseets.mSeelf);35. 36. retturnnAnndrooidRRunttimee:rregiisteerNaativveMeethoods(37. ennv,kBiindeerPrroxyyPatthNaame,38. gBBindderPProxxyMeethoods,NEELEMM(gBBindderPProxxyMeethoods);39. 回到到前面的的javvaObbjecctFoorIBBindder函函数中,下下面这段段代码:vieww pllainn1. if(
35、vall-cchecckSuubcllasss(&ggBinnderrOfffsetts)2. /Oneeoffouuroown!3. jobbjecctoobjeect=sstattic_casst(vaal.gget()-obbjecct();4. /pprinntf(obbjecctFoorBiindeer%p:itsoourownn%pp!nn,vall.geet(),oobjeect);5. retturnnobbjecct;6. 前面面说过,这这里传进进来的参参数是一一个BppBinnderr的指针针,而BBpBiindeer:cheeckSSubcclasss继承承于父类类IBi
36、indeer:cheeckSSubcclasss,它它什么也也不做就就返回ffalsse。 于是是函数继继续往下下执行:vieww pllainn1. jobjjecttobbjecct=(jjobjjectt)vaal-finndObbjecct(&gBiindeerPrroxyyOfffsetts); 由于于这个BBpBiindeer对象象是第一一创建,它它里面什什么对象象也没有有,因此此,这里里返回的的objjectt为NULLL。 于是是函数又又继续往往下执行行:vieww pllainn1. objeect=eenv-NeewObbjecct(ggBinnderrProoxyOOff
37、ssetss.mCClasss,gBiindeerPrroxyyOfffsetts.mmConnstrructtor); 这里里,就创创建了一一个BiindeerPrroxyy对象了了。创建建了之后后,要把把这个BBpBiindeer对象象和这个个BinnderrProoxy对对象关联联起来:vieww pllainn1. env-SeetInntFiieldd(obbjecct,gBiindeerPrroxyyOfffsetts.mmObjjectt,(intt)vaal.gget(); 就是是通过BBindderPProxxy.mmObjjectt成员变变量来关关联的了了,Biindeer
38、Prroxyy.mOObjeect成成员变量量记录了了这个BBpBiindeer对象象的地址址。 接下下去,还还要把它它放到BBpBiindeer里面面去,下下次就要要使用时时,就可可以在上上一步调调用BppBinnderr:ffinddObjj把它找找回来了了:vieww pllainn1. val-atttacchObbjecct(&gBiindeerPrroxyyOfffsetts,reffObjjectt,2. jniienvv_too_jaavavvm(eenv),pproxxy_ccleaanupp); 最后后,就把把这个BBindderPProxxy返回回到anndrooid_o
39、s_BinnderrIntternnal_gettConntexxtObbjecct函数数,最终终返回到到最开始始的SeerviiceMManaagerr.geetISServviceeMannageer函数数中来了了,于是是,我们们就获得得一个BBindderPProxxy对象象了。 回到到SerrvicceMaanagger.gettISeerviiceMManaagerr中,从从下面语语句返回回:vieww pllainn1. sSerrvicceMaanagger=SServviceeMannageerNaativve.aasInnterrfacce(BBindderIInteernaal.ggetCConttexttObjjectt(); 相当当于是:vieww pllainn1. sSerrvicceMaanagger=SServviceeMannageerNaativve.aasInnterrfacce(nnewBinnderrProoxy();