为了了解Android的事件分发,我们先需要了解一下GUI的上下文涉及的内容,这篇只是做简单的介绍,在分析完事件后,会详细的分析总结这些内容
基于Android 2.3源码的分析总结
GUI其实是为了做了几件事情:
是否还有其他???
涉及到的相关内容
因为需要找到一个突破口,如果但从SurfaceFlinger或者Wms入口的话,很难看到具体的调用的地方,于是还是从Ams入手是最好的
GUI系统结构图
Ams: ActivityManagerService, 这个名字感觉还是不够明确的,这个并不单单做这个事情,ActivityManagerService 是作为server端,管理系统中的四大组件的
控制管理四大基本组件
这里也只是将Activity相关的部分,进行了一些类图的汇总
总结如下:
Client
Instrumentation在和Ams进行主动通讯时,是跨进程的,跨进程通讯使用的是IPC,而IPC的套路是,Client和Server共同实现相同的接口,然后通过Binder来调用,这里也是符合Android自己定义的Binder的流程的
Server
ActivityManagerService在收到了客户端的请求操作后,会做一些逻辑的处理,以通过Launcher来启动一个应用为例
Client
Server
bind对应的application,即Application的初始化
将要启动的Activity来继续操作,通过ApplicationThreadProxy通知启动Activity,activity便进行了launch
端上在launch时,会通过Instrument来通知Activity进行attach,onCreate以及生命周期相关方法onStart(), onResume()的调用
Ams只是控制Activity的堆栈以及应用之间应该如何操作,自己并不做Activity的启动以及销毁等操作,因为这个是具体应用来控制的,即Client的事情
数据的通道: 这个与我们常见写的callback的方式其实没有太大的差异,只不过涉及的类以及内容复杂了些,Activity通过Ams的proxy来请求服务端,我想做什么,服务端在处理了之后,通过ApplicationThread的Proxy来通知端上,你应该做什么.
Ams相关讲解
老罗的Android之旅 activity相关
DroidPlugin github地址
个人之前也在之前公司的app中集成过360的DroidPlugin,这个插件实现的挺巧妙的,而且各种hook,也看出了360的hook与hack的精神,插科打诨一下~
个人之前的DroidPluigin的随笔,写的很散,而且条理性不是很清晰,但是是个人学习的踪迹,现在来看,还是别有一番趣味的
在说360的这个插件框架之前,再来简化的说一下Ams相关的流程图
图示如下:
根据这个图,我们再来梳理一下:
这个图只是以Activity的启动为例,其实Service,ContentProvider,BroadcastReceiver等组件均由ActivitiyManagerService来控制,Client均是通过ActivityManagerProxy来做这些请求操作,然后ActivityManagerService来通过ApplicationThreadProxy来通知客户端应该做如何的响应的.
DroidPlugin的偷梁换柱
我们知道,Android的四大组件,除了广播,其他的组件,Activity,Service,ContentProvider都是需要在资源清单文件中注册的,那么对于动态加载,肯定是这些资源清单文件中,没有的这几个组件,通过查看上节中的分析,得知这四大组件的通讯模型,是否能够做些手脚,便可以实现这些,360的DroidPlugin便实现了这些.
上图中,我已经标注了Client和Server的分界线,而且进出口都是明确的,进入ActivityManagerService的入口是ActivityManagerProxy,查看ActivityManagerProxy的源码,看到了我们垂涎欲滴的方法,startActivity, startService,那么更改下这个代理,把我们要启动的Activity换位已有的Activity,这样系统就认为我们启动的Activity是合法的了.参数如何处理呢?直接将参数以其他的方式存入到Intent中即可
这个只是启动合法了,那么Activity在通过ApplicationThreadProxy时通知我们启动Activity时,这个Acitivy是我们欺骗系统用的Activity,这时,通过Instrumentation是要启动我们想要的Activity的,那么我们再将Instrumentation中的要启动的Activity我们自己加载,便可以Activity的动态加载了.
如下图:
这个后续再分享吧,todo一下
其实包括我们接下来要说的View的事件分发,其实能看出来,单方向的数据流设计是最简单的,而且是最不容易出问题的.
A 请求B,我要做什么,B经过处理后,通知A,你可以做什么,其实Ams的模型就是这个的复杂化.
A想要请求B,但是A摸不到B,A只能通过B的代理来请求B,B经过自己的N多处理流程,最终通过其他方式来通知A,你可以做什么.
其实说白了,这个就是请求响应的复杂化,
A request B, B response A
我们最常见的写代码的逻辑,举例如下:
A是UI的控件,B是处理逻辑的控制器,A点击后,调用B的方法,告诉B我想做什么
B在收到这个事件后,经过自己的处理逻辑,告诉A处理的结果.
以上内容部分参考老罗的android之旅以及柯元旦的源码分析
相关图位于个人的github上