Android应用程序绑定服务(bindService)的过程源代码分析.pdf
《Android应用程序绑定服务(bindService)的过程源代码分析.pdf》由会员分享,可在线阅读,更多相关《Android应用程序绑定服务(bindService)的过程源代码分析.pdf(19页珍藏版)》请在三一文库上搜索。
1、 Android 应用程序组件 Service 与Activity 一样,既可以在新的进程中启动,也可以在应用程序进程内部启动;前面我们已经分析了在 新的进程中启动 Service 的过程,本文将要介绍在应用程序内部绑定Service 的过程,这是一种在应用程序进程内部启动Service 的方法。 在前面一篇文章 Android 进程间通信( IPC)机制 Binder 简要介绍和学习计划中,我们就曾经提到,在Android 系统中,每一个应用程 序都是由一些 Activity 和Service 组成的,一般 Service 运行在独立的进程中,而Activity 有可能运行在同一个进程中,也
2、有可能运行在不同的 进程中;在接下来的文章中,Android 系统在新进程中启动自定义服务过程(startService )的原理分析 一文介绍了在新的进程中启动 Service 的过程, Android 应用程序启动过程源代码分析一文介绍了在新的进程中启动Activity 的过程,而 Android 应用程序内部启动 Activity 过程( startActivity )的源代码分析 一文则介绍了在应用程序进程内部启动Activity 的过程;本文接过最后一棒,继续介绍在应用程序进程 内部启动 Service 的过程,这种过程又可以称在应用程序进程内部绑定服务(bindService )的
3、过程,这样,读者应该就可以对Android 应用 程序启动 Activity 和Service 有一个充分的认识了。 这里仍然是按照老规矩,通过具体的例子来分析Android 应用程序绑定 Service 的过程,而所使用的例子便是前面我们在介绍Android 系统广播机制的一篇文章Android 系统中的广播( Broadcast )机制简要介绍和学习计划中所开发的应用程序 Broadcast 了。 我们先简单回顾一下这个应用程序实例绑定Service 的过程。在这个应用程序的MainActivity 的onCreate 函数中,会调用 bindService 来绑定一个计数器服务Count
4、erService,这里绑定的意思其实就是在MainActivity 内部获得 CounterService 的接口,所以,这个过程的第 一步就是要把 CounterService 启动起来。当 CounterService 的onCreate 函数被调用起来了,就说明CounterService 已经启动起来了,接下 来系统还要调用 CounterService 的onBind 函数,跟 CounterService要一个 Binder 对象,这个 Binder对象是在 CounterService 内部自定义的 CounterBinder 类的一个实例,它继承于Binder 类,里面实现一
5、个 getService 函数,用来返回外部的CounterService 接口。系统得到这个 Binder 对象之后,就会调用MainActivity 在bindService 函数里面传过来的 ServiceConnection实例的onServiceConnected函数,并把这个 Binder 对象以参数的形式传到onServiceConnected函数里面,于是, MainActivity 就可以调用这个 Binder 对象的 getService 函数来获得 CounterService 的接口了。 这个过程比较复杂,但总体来说,思路还是比较清晰的,整个调用过程为MainActiv
6、ity.bindService-CounterService.onCreate- CounterService.onBind-MainActivity.ServiceConnection.onServiceConnection-CounterService.CounterBinder.getService。下面, 我们就先用一个序列图来总体描述这个服务绑定的过程,然后就具体分析每一个步骤。 点击查看大图 Step 1. ContextWrapper.bindService 这个函数定义在 frameworks/base/core/java/android/content/ContextWrap
7、per.java文件中: java 01.publ i c c l ass Cont ext W r apperex t ends Cont ext 02.Cont ex tmBas e; 03 . . . . . 04. 05. Over r i de 06.publ i cbool ean bi ndSer vi ce( I nt ents er vi ce,Ser vi ceConnect i on c onn, 07.i ntf l ags) 08.r et ur n mBase. bi ndSer vi ce( ser v i c e,conn,f l ags) ; 09. 10.
8、11 . . . . . 12. 这里的 mBase 是一个 ContextImpl 实例变量,于是就调用ContextImpl 的bindService 函数来进一步处理。 Step 2. ContextImpl.bindService 这个函数定义在 frameworks/base/core/java/android/app/ContextImpl.java文件中: java 01.c l assCont ext I mplex t ends Cont ex t 02 . . . . . 03. 04. Over r i de 05.publ i cbool ean bi ndSer vi
9、 ce( I nt ents er vi ce,Ser vi ceConnect i on c onn, 06.i ntf l ags) 07.I Ser vi ceConnec t i on s d; 08.i f( mPac kageI nf o ! = nul l ) 09.sd = mPack ageI nf o. get Ser v i c eDi spat c her ( conn,get Out er Cont ext ( ) , 10.m Mai nThr ead. get Handl er ( ) ,f l ags ) ; 11.el se 12 . . . . . 13.
10、14.t r y 15.i ntr es = Act i vi t y M anager Nat i ve. get Def aul t ( ) . bi ndSer vi ce( 16.m Mai nThr ead. get Appl i c at i onThr ead( ) ,get Ac t i vi t yTok en( ) , 17.ser v i c e,ser vi ce. r esol v eTypeI f Needed( get Cont ent Res ol ver ( ) ) , 18.sd,f l ags) ; 19 . . . . . 20.r et ur n r
11、es! = 0; 21.cat ch( Remot eExcept i one) 22.r et ur n f al se; 23. 24. 25. 26 . . . . . 27. 28. 这里的 mMainThread 是一个 ActivityThread 实例,通过它的 getHandler 函数可以获得一个 Handler 对象,有了这个 Handler 对象后,就 可以把消息分发到 ActivityThread 所在的线程消息队列中去了,后面我们将会看到这个用法,现在我们暂时不关注,只要知道这里从 ActivityThread 处获得了一个 Handler 并且保存在下面要介绍的Se
12、rviceDispatcher中去就可以了。 我们先看一下 ActivityThread.getHandler的实现,然后再回到这里的bindService 函数来。 Step 3. ActivityThread.getHandler 这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java文件中: java 01.publ i c f i nalcl ass Act i vi t yThr ead 02 . . . . . 03. 04.f i nalH mH = new H( ) ; 05. 06 . . . . .
13、 07. 08.pr i v at e f i nalcl as s H ex t ends Handl er 09 . . . . . 10. 11.publ i c v oi d handl eMess age( Mes sage msg) 12 . . . . . 13. 14. 15 . . . . . 16. 17. 18 . . . . . 19. 20.f i nalHandl erget Handl er ( ) 21.r et ur n mH; 22. 23. 24 . . . . . 25. 这里返回的 Handler 是在ActivityThread 类内部从 Handl
14、er 类继承下来的一个 H类实例变量。 回到Step 2 中的ContextImpl.bindService函数中,获得了这个Handler 对象后,就调用 mPackageInfo.getServiceDispatcher函数来获 得一个 IServiceConnection 接口,这里的 mPackageInfo 的类型是 LoadedApk ,我们来看看它的 getServiceDispatcher函数的实现,然后再 回到ContextImpl.bindService函数来。 Step 4. LoadedApk.getServiceDispatcher 这个函数定义在 framework
15、s/base/core/java/android/app/LoadedApk.java文件中: java 01.f i nalcl as s LoadedApk 02 . . . . . 03. 04.publ i cf i nalI Ser v i ceConnect i on get Ser vi c eDi s pat cher ( Ser vi ceConnect i on c , 05.Cont ex tcont ext ,Handl erhandl er ,i ntf l ags ) 06.sy nchr oni z ed ( mSer vi ces) 07.LoadedApk.
16、Ser vi c eDi s pat chersd = nul l ; 08.HashM ap map= m Ser vi ces . get ( c ont ext ) ; 09.i f( m ap ! = nul l ) 10.sd = map. get ( c ) ; 11. 12.i f( sd = nul l ) 13.sd = new Ser vi ceDi s pat c her ( c,c ont ext ,handl er ,f l ags) ; 14.i f( m ap = nul l ) 15.m ap = new HashMap ( ) ; 16.m Ser vi ce
17、s. put ( c ont ext ,map) ; 17. 18.m ap. put ( c,s d) ; 19.el se 20.sd. v al i dat e( cont ext ,handl er ) ; 21. 22.r et ur n s d. get I Ser v i c eConnec t i on( ) ; 23. 24. 25. 26 . . . . . 27. 28.s t at i cf i nalc l assSer vi ceDi spat c her 29.pr i vat ef i nalSer vi c eDi s pat cher . I nner Co
18、nnect i on mI Ser v i c eConnect i on; 30.pr i vat ef i nalSer vi c eConnec t i onmConnec t i on; 31.pr i vat ef i nalHandl erm Act i vi t y Thr ead; 32 . . . . . 33. 34.pr i vat est at i ccl ass I nner Connect i onex t ends I Ser vi ceConnect i on. St ub 35.f i nalW eak Ref er enc e mDi spat cher ;
19、 36 . . . . . 37. 38.I nner Connect i on( LoadedApk . Ser vi ceDi spat chers d) 39.m Di s pat cher= new W eakRef er ence( s d) ; 40. 41. 42 . . . . . 43. 44. 45 . . . . . 46. 47.Ser vi ceDi s pat c her ( Ser v i c eConnec t i on c onn, 48.Cont ex tcont ex t ,Handl eract i vi t y Thr ead,i ntf l ags
20、) 49.mI Ser v i c eConnect i on = new I nner Connec t i on( t hi s) ; 50.mConnect i on = conn; 51.mAct i v i t yThr ead= ac t i v i t yThr ead; 52 . . . . . 53. 54. 55 . . . . . 56. 57.I Ser vi ceConnec t i on get I Ser v i c eConnect i on( ) 58.r et ur n mI Ser vi ceConnect i on; 59. 60. 61 . . . .
21、 . 62. 63. 64 . . . . . 65. 在getServiceDispatcher函数中,传进来的参数 context 是一个MainActivity 实例,先以它为 Key 值在mServices 中查看一下,是不是已 经存在相应的 ServiceDispatcher实例,如果有了,就不用创建了,直接取出来。在我们这个情景中,需要创建一个新的 ServiceDispatcher。在创建新的 ServiceDispatcher实例的过程中,将上面传下来ServiceConnection参数 c和Hanlder 参数保存在了 ServiceDispatcher实例的内部,并且创建
22、了一个InnerConnection 对象,这是一个 Binder 对象,一会是要传递给ActivityManagerService 的,ActivityManagerServic后续就是要通过这个 Binder 对象和 ServiceConnection通信的。 函数getServiceDispatcher最后就是返回了一个 InnerConnection 对象给 ContextImpl.bindService函数。回到 ContextImpl.bindService 函数中,它接着就要调用ActivityManagerService的远程接口来进一步处理了。 Step 5. Activit
23、yManagerService.bindService 这个函数定义在 frameworks/base/core/java/android/app/ActivityManagerNative.java文件中: java 01.c l assAc t i vi t yManager Pr oxy i m pl ement s I Act i vi t y M anager 02. 03 . . . . . 04. 05.publ i ci ntbi ndSer vi ce( I Appl i cat i onThr ead c al l er ,I Bi ndert oken, 06.I nt
24、ents er vi ce,St r i ng r esol vedTy pe,I Ser vi ceConnect i on connec t i on, 07.i ntf l ags)t hr ows Remot eExc ept i on 08.Par celdat a = Par cel . obt ai n( ) ; 09.Par celr epl y = Par cel . obt ai n( ) ; 10.dat a. wr i t eI nt er f aceTok en( I Act i v i t yManager . descr i pt or ) ; 11.dat a.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 应用程序 绑定 服务 bindService 过程 源代码 分析
链接地址:https://www.31doc.com/p-5012089.html