getSystemService的跟踪

getSystemService,Android开发经常需要调用的方法,以下开始跟踪以下该方法的整个流程
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

首先调用到activity类中的getSystemService,mWindowManager和mSearchManager可以在这里直接获得,该部分暂不分析。最后会调用到activity父类的getSystemService方法

getSystemService的跟踪_第1张图片
**activity.java**

activity继承ContextThemeWrapper,这里return getBaseContext().getSystemService(name);
(这里附上一段个人对Context子类功能的理解.ContextWrapper仅仅是对Context的简单封装,如果要对Context修改,我们只需要修改ContextWrapper,而不需要对通用的Context进行修改,ContextWrapper的目的仅此而已。而ContextThemeWrapper只是在ContextWrapper的基础上加入了Theme相关的一些内容,对于Activity来说需要处理一些Theme相关的东西,但是对于Service来说只需继承ContextWrapper,因为Service不需要处理Theme相关的内容)

getSystemService的跟踪_第2张图片
**ContextThemeWrapper.java**

getBaseContext()调用ContextWrapper的方法,返回mBase,关于mBase是从哪里来的,可以猜到是来自于context的实现类ContextImpl,具体研究在http://www.jianshu.com/p/5dce399c013e

接下来就要去调查ContextImpl类的getSystemService:

**ContextImpl.java**

继续追踪SystemServiceRegistry.getSystemService(this, name)

getSystemService的跟踪_第3张图片
**SystemServiceRegistry.java**

到这里我们可以发现,代码会去SYSTEM_SERVICE_FETCHERS这个HashMap去得到系统服务,定义代码如下:

SYSTEM_SERVICE_FETCHERS

接着我们去寻找该HashMap数据进入的地方

getSystemService的跟踪_第4张图片
**registerService**

显然,代码是通过registerService这个静态方法不断add数据到HashMap。下面我们就需要去寻找registerService在哪里被调用。

getSystemService的跟踪_第5张图片
**静态块**

注册service都写在一个静态块里,static语句的用法说明链接

下面会去ServiceManager里查找服务

getSystemService的跟踪_第6张图片
ServiceManager.java

可以看到代码会去sCache缓存里去获取service信息,如果缓存里没有会通过ServiceManager去底层调用,这块暂且不讨论。我们先去调查,sCache这个缓存数据是从哪来的。在ServiceManager.java里可以找到如下代码:

ServiceManager.java

接下来就去寻找initServiceCache的调用地方了,思考了半天,在ActivityThread.java里发现其踪迹

getSystemService的跟踪_第7张图片
ActivityThread.java

bindApplication方法,个人猜测应该是app启动流程中,绑定app和进程的动作,这个后续去追一下。

其中的Map services数据是怎么put进去的在上述代码中还是没有表现出来,我猜测是在这,ServiceManager中的addService方法。

getSystemService的跟踪_第8张图片
ServiceManager.java

看下getIServiceManager返回什么

getSystemService的跟踪_第9张图片
ServiceManager.java

返回IServiceManager接口,继续追下去

getSystemService的跟踪_第10张图片
ServiceManagerNative.java

看源码的描述,是将binder对象转为一个servicemanager的接口,并产生一个代理供使用。其中

    IServiceManager in =
        (IServiceManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }

这段代码是在查询是否是进程内通讯。

在ServiceManagerNative.java中的内部类ServiceManagerProxy中可以找到addService方法

getSystemService的跟踪_第11张图片
addService

另外也可以找到getservice方法

getSystemService的跟踪_第12张图片
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是服务端。

你可能感兴趣的:(getSystemService的跟踪)