在平时的android开发中,我们经常会通过Context来获取系统服务,比如ActivityManagerService,AccountManagerService等系统服务,今天我们就来看下getSystemService(String name)的整个调用流程。
1.找到Context的实现类
打开Context类,可以看到Context是一个抽象类,那么getSystemService一定是在其实现类来调用的,具体我们都猜得到ContextImpl
1 | public abstract class Context { |
为什么是ContextImpl呢?我们都知道当我们启动一个Activity的时候,其实是在ActivityThread performLaunchActivity方法中启动的,这一点可以参考上一篇文章” Activity启动流程 “,一个Activity的入口是
ActivityThread的main方法,看下main方法
1 | public static void main(String[] args) { |
可以看到上面在main方法中,调用了自身的attach方法。
1 | private void attach(boolean system) { |
可以看到在main方法中,通过调用activityThread的attach方法,并且参数为false,表示非系统应用,会通过binder与
ActivityManagerService通信,并且最后会调用performLaunchActivity方法。
1 | private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { |
可以看到创建Context的具体实现是在ActivityThread#createBaseContextForActivity方法中完成的
1 | private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) { |
好了,到现在位置我们可以看到Context的实现类就是ContextImpl,那么关于getSystemService的具体实现也应该在ContextImpl里面了。
2.getSystemService的具体实现
ContextImpl#getSystemService的实现如下
1 | @Override |
可以看到实际上ContextImpl也是通过SystemServiceRegistry.getSystemService来获取具体的服务,那么下面看看SystemServiceRegistry.getSystemService
1 | public static Object getSystemService(ContextImpl ctx, String name) { |
可看到实际上获取系统服务是通过ServiceFetcher的getService来获取的,并且SYSTEM_SERVICE_FETCHERS实际上就是一个Map实例,所以肯定是通过put方法为它赋值的。通过搜索,我们发现只有一个地方在做put操作:
1 | private static <T> void registerService(String serviceName, Class<T> serviceClass, |
顾名思义,这个方法是用来注册系统服务的,当注册系统服务的时候,就会调用到SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);将当前的服务put到SYSTEM_SERVICE_NAMES集合中
1 | static abstract interface ServiceFetcher<T> { |
ServiceFetcher是一个接口,又三个实现类:CachedServiceFetcher,StaticServiceFetcher,StaticOuterContextServiceFetcher,具体不同的服务可能对应不同的实现类
这些系统服务都是在SystemServiceRegistry的static静态代码块中进行注册的,如下:
1 | static { |
这里,我们以ActivityManagerService为例来进行学习。在注册该服务的时候,将Context.ACTIVITY_SERVICE作为键,将CachedServiceFetcher作为值,并且重写了createService方法,createService是在当前ServiceFetcher的
getService里执行的,这里会返回一个ActivityManager的实例,ctx.mMainThread.getHandler()就是ActivityThread中的H,在”activity 启动流程”一文,我们已经知道了,启动activity最终就会通过ActivityThread$H的handleMessage进行处理,实际上,包括service的启动以及Broadcast的处理都是在H里处理的,这个后面会细说。
3.在SystemServer中启动系统服务
我们知道android系统第一次开机的时候,会通过ZygoteInit来启动SystemServer,简单看下ZygoteInit#main方法
1 | public static void main(String argv[]) { |
此时会执行SystemServer的main方法
1 | public static void main(String[] args) { |
比较简单,内部运行自身的run方法
1 | private void run() { |
在上面的run方法中,和service相关的操作主要就是通过下面的方法启动:开机,核心,以及其他服务
1 | startBootstrapServices(); |
其实在这个三个start服务中,不止启动系统服务,还会将这些服务和ServiceManager进行关联,以方便ServiceManager的管理
比如:
1 | ServiceManager.addService(Context.INPUT_SERVICE, inputManager); |
好了,到这里为止,getSystemService的流程就走完了