getSystemService,Android开发经常需要调用的方法,以下开始跟踪以下该方法的整个流程
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
首先调用到activity类中的getSystemService,mWindowManager和mSearchManager可以在这里直接获得,该部分暂不分析。最后会调用到activity父类的getSystemService方法
**activity.java**activity继承ContextThemeWrapper,这里return getBaseContext().getSystemService(name);
(这里附上一段个人对Context子类功能的理解.ContextWrapper仅仅是对Context的简单封装,如果要对Context修改,我们只需要修改ContextWrapper,而不需要对通用的Context进行修改,ContextWrapper的目的仅此而已。而ContextThemeWrapper只是在ContextWrapper的基础上加入了Theme相关的一些内容,对于Activity来说需要处理一些Theme相关的东西,但是对于Service来说只需继承ContextWrapper,因为Service不需要处理Theme相关的内容)
getBaseContext()调用ContextWrapper的方法,返回mBase,关于mBase是从哪里来的,可以猜到是来自于context的实现类ContextImpl,具体研究在http://www.jianshu.com/p/5dce399c013e
接下来就要去调查ContextImpl类的getSystemService:
**ContextImpl.java**继续追踪SystemServiceRegistry.getSystemService(this, name)
**SystemServiceRegistry.java**到这里我们可以发现,代码会去SYSTEM_SERVICE_FETCHERS这个HashMap去得到系统服务,定义代码如下:
SYSTEM_SERVICE_FETCHERS接着我们去寻找该HashMap数据进入的地方
**registerService**显然,代码是通过registerService这个静态方法不断add数据到HashMap。下面我们就需要去寻找registerService在哪里被调用。
**静态块**注册service都写在一个静态块里,static语句的用法说明链接
下面会去ServiceManager里查找服务
ServiceManager.java可以看到代码会去sCache缓存里去获取service信息,如果缓存里没有会通过ServiceManager去底层调用,这块暂且不讨论。我们先去调查,sCache这个缓存数据是从哪来的。在ServiceManager.java里可以找到如下代码:
ServiceManager.java
接下来就去寻找initServiceCache的调用地方了,思考了半天,在ActivityThread.java里发现其踪迹
ActivityThread.javabindApplication方法,个人猜测应该是app启动流程中,绑定app和进程的动作,这个后续去追一下。
其中的Map<String, IBinder> services数据是怎么put进去的在上述代码中还是没有表现出来,我猜测是在这,ServiceManager中的addService方法。
ServiceManager.java看下getIServiceManager返回什么
ServiceManager.java返回IServiceManager接口,继续追下去
ServiceManagerNative.java看源码的描述,是将binder对象转为一个servicemanager的接口,并产生一个代理供使用。其中
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
这段代码是在查询是否是进程内通讯。
在ServiceManagerNative.java中的内部类ServiceManagerProxy中可以找到addService方法
addService另外也可以找到getservice方法
getservice其实整个getSystemService的方法就是Android binder进程通信如下三步曲的第二部,通过注册时定义好的name获得从ServiceManager里获取到相应的系统服务:
- 注册服务(addService):Server进程要先注册Service到ServiceManager。该过程:Server是客户端,ServiceManager是服务端。
- 获取服务(getService):Client进程使用某个Service前,须先向ServiceManager中获取相应的Service。该过程:Client是客户端,ServiceManager是服务端。
- 使用服务:Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互。该过程:client是客户端,server是服务端。
网友评论