context.getSystemService 源代码解析
先看图,下图主要说明了从context.getSystemService开始到获取到目标系统service对象所做的第一步流程。其中涉及到了核心类ServiceFetcher和SystemServiceRegistry。
SystemServiceRegistry主要负责缓存系统服务名字(即Context.ACTIVITY_SERVICE)和ServiceFectcher的映射Map,类加载节点就会将这些信息存储进去。每个APP都会自己有个独立进程,所以这里每个APP都会有一个 SystemServiceRegistry 对象。
接着我们看ServiceFetcher做了什么事。
ServiceFetcher
首先ServiceFetcher是定义在 SystemServiceRegistry 中的,它是一个接口,其下有两个实现抽象类,以便系统服务在SystemServiceRegistry类加载阶段去实例化自己的ServiceFetcher。
CachedServiceFetcher
CachedServiceFetcher,核心思想是从对应的contextImpl对象的缓存池中获取服务对象,如果不存在则新创建一个。
因为这里可能涉及到多线程问题,所以代码中通过对contextImpl中的缓存数组加锁,来保证多线程的安全。
StaticServiceFetcher
StaticServiceFetcher 不会针对每个contextImpl做缓存,直接在当前进程中,缓存一个对象。用起来比较简单,也是线程安全的。
接下来,继续看方法 createService()。
createService()
createService()方法主要用于创建service对象实例,其实创建的是代理对象实例。我们以 ActivityManager 为例来看下。
首先 ActivityManager 的ServiceFetcher 时候,createService代码如下:
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
可见,这里是直接new了一个对象。
所以拿ActivityManager为例,通过context.getSystemService方法返回的是ActivityManager对象,但是我们进入到AM对象中,可以看到,当我们实际使用其里边方法时,都会先调用getTaskService()方法获取一个IActivityManager,然后再调用具体方法。这是因为我们直接通过new出来的对象拿到的是AM的代理对象,AM服务系统只有一个,不会因为我们进程new一个对象就会出现一个新的服务。
所以这里接着看getTaskService的源码,可以层层往下看,最终可以看到,它其实是从ServiceManager中拿到了binder对象,然后使用其代理对象通过AIDL方式来间接调用真正的AM中的方法。
所有的系统服务使用方式都和AM这种方式一致,最终都会通过ServiceManager来找到对应服务的代理,然后代理通过AIDL方式和实际服务进行交互。
OK,后续我们研究下ServiceManger是如何获取服务的。