前言
此篇博客是在上篇《模拟AIDL实现进程间通信》的基础上进行解析ActivityManager,ServiceManager,PackgeManager框架的。如有疑问请看上篇文章。如有错误之处谢谢指正,以免后排同学入坑。
正文ActivityManager
ok,这篇文章其实也就是了解整个Activity框架,在这里面涉及到的有进程间通信机制,代理模式,如果看了我上篇的《模拟AIDL实现进程间通信》那么这篇文章就能很好的理解这篇文章了。
ActivityManager:官方文档介绍到其作用,是与系统所有正在运行着的Acitivity进行交互,对系统所有运行中的Activity相关信息(Task,Memory,Service,App)进行管理和维护;提供了相应的接口用于获取这些信息。
ok先来张类图(网络搜索出来的)
ok,通过这个类图先说明下,IBinder,Binder,IInterface,ActivityManager是为可以与用户交互的,也就是可以直接导包进行使用,而IActivityManager,ActivityManagerProxy,ActivityManagerNative用户就不能进行导包使用了,而这个ActivityManagerService那就是在系统上面存在的了。
先贴下这些用户不能直接使用的源码位置(此位置为完全源码的位置,不是SDK里面的,不过IActivityManager,ActivityManagerNative,ActivityManagerProxy在SDK的OS包下能找到,至于为什么不能导包引用是因为在类的顶是那个加了{@hide},这个在编译完成打成jar包后就不能进行引用了)。
Ok,先来介绍下这些类的关系,从上图了解到,IActivityManager继承了Interface接口。而ActivityManagerNative和ActivityManagerPorxy实现了这个IActivityManager接口。
ActivityManager持有的是这个ActivityManagerPorxy代理对象,这样,只需要操作这个代理对象就能操作其业务实现的方法。那么真正实现其也业务的则是ActivityManagerService。
咱们再来说说这个ActivityManagerNative这个类,他继承了Binder而Binder实现了IBinder接口。其子类则是ActivityManagerService。
OK,关系介绍完了,多的不说了,因为这个整个结构其实跟上一篇的文章其实差不多,再去细讲感觉有点多余,如果有懵逼的同学,请移步上一篇文章。
好了,直接通过一个流程我们来了解下他的结构吧。举个简单的例子,ActivityManager的getRunningServices方法,这个方法是用来获取正在运行的服务列表。以下是此方法代码。
从以上代码片段可以看出获取运行服务方法是通过ActivityManagerNative.getDefault();方法获取的一个对象然后调用getServices(maxNum, 0);方法来获取的。我们先来看下getDefault()是做什么的。
返回了一个IActivityManager对象,因此这个getServices(maxNum, 0);是IActivityManager接口的方法。
那么我们看下这个gDefault是什么,(这一块有点复杂哦,涉及到了两个代理对象,别搞懵了)
从以上代码可以看出是一个单例对象,这个Singleton就以泛型来创建不同的单例(第一次看到这样写单例的,学习了)。
那么看下这个Create()方法里面都干了些什么,ServiceManager.getService(“activity”);通过ServiceManager的getService(“activity”)获取一个IBinder对象,这个IBinder对象上篇文章也讲了是获取的一个代理,而不是真正的IBinder,即为在Binder对象里面的一个BinderPorxy这个内部类代理对象,有图为证:
通过反射获取到的IBinder对象看的出来就是这个代理BinderProxy(如果这里有懵圈的同学可以移步看下上篇文章,至于怎么获取到这个代理的这里先不讲这个,有机会会讲到这个ServiceManager所以在这也不做多说了。)
获取到这个IBinder对象后调用了ActivityManagerNative的asInterface方法并传进去这个IBinder对象获得了一个IActivityManager对象,这也是获取代理对象,值不过这个代理对象不在是Binder的了,而是ActivityManagerNative的代理对像,看下这个方法
上篇文章介绍到这个queryLocalInterface方法是IBinder对象的方法,其实现是在Binder里面,作用就是验证并获取这个descriptor标识的IActivityManager对象。(上面也说到了ActivityManagerPorxy实现了IActivityManger)如果不为null,则返回,为null则创建一个代理返回。有图为证:
因此这个ActivityManger里面获取运行服务列表里的getServices(maxNum, 0);是代理ActivityManagerPorxy对象调用的,那么看下这个方法做了什么。
如果看了上一篇文章,那么这一部分就很熟悉了,将要传输的参数写入到Parcel对象中,并使用在创建这个代理对象传进来的IBinder对象调用transact方法将参数写出去,GET_SERVICES_TRANSACTION为一个标识,也能说是命令。当写出去后ActivityManagerNative就会调用ontransact方法,然后通过GET_SERVICES_TRANSACTION进行判断执行其对应操作。
getServices(maxNum, fl);调用的是ActivityManagerService里面的方法,然后就获得了。一个集合,并将这集合的内容一条条的写出去。然后接收。他们的Binder通信我就不细说了哈,上篇文章有详细写到。哈哈,这如果继续追踪源码下去就长了,我们这篇注重讲ActivityManager框架。
关于:中科研拓
深圳市中科研拓科技有限公司专注提供软件外包、app开发、智能硬件开发、O2O电商平台、手机应用程序、大数据系统、物联网项目等开发外包服务,十年研发经验,上百成功案例,中科院软件外包合作企业。通过IT技术实现创造客户和社会的价值,致力于为用户提供很好的软件解决方案。联系电话400-0316-532,邮箱sales@zhongkerd.com,网址www.zhongkerd.com