前语

前面该系列文章咱们剖析了用户态第一个进程init进程,和敞开Java世界的Zygote进程的流程剖析,本篇文章咱们来剖析一下SystemServer进程,即体系服务进程。

体系服务进程由Zygote进程创立而来,它的效果是用于创立和办理体系服务,比方咱们熟知的AMS、WMS和PMS等都是由它来创立的,所以它能够看成是Java Framework的办理者。

正文

话不多说,咱们就来看看该进程的发动流程。

Zygote发动SystemServer进程

该部分内容在上一篇Zygote进程剖析中有所触及,首要便是ZygoteInit中的forkSystemServer办法,在该办法中底层经过fork体系调用先创立进程,然后调用handleSystemServerProcess办法来处理体系服务进程。大致代码如下:

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    private static Runnable forkSystemServer(String abiList, String socketName,
621            ZygoteServer zygoteServer) {
622        ...
            //各种参数
641        String args[] = {
642            "--setuid=1000",
643            "--setgid=1000",
644            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
645            "--capabilities=" + capabilities + "," + capabilities,
646            "--nice-name=system_server",
647            "--runtime-args",
                //终究调用的Java类
648            "com.android.server.SystemServer",
649        };
650        ZygoteConnection.Arguments parsedArgs = null;
651
652        int pid;
653
654        try {
655            parsedArgs = new ZygoteConnection.Arguments(args);
656            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
657            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
658
               //经过fork创立了新进程,即体系服务进程
660            pid = Zygote.forkSystemServer(
661                    parsedArgs.uid, parsedArgs.gid,
662                    parsedArgs.gids,
663                    parsedArgs.debugFlags,
664                    null,
665                    parsedArgs.permittedCapabilities,
666                    parsedArgs.effectiveCapabilities);
667        } catch (IllegalArgumentException ex) {
668            throw new RuntimeException(ex);
669        }
670
671        //体系服务进程运转分支
672        if (pid == 0) {
673            if (hasSecondZygote(abiList)) {
674                waitForSecondaryZygote(socketName);
675            }
676            //体系服务进程不需求监听socket,所以关闭
677            zygoteServer.closeServerSocket();
                //处理体系服务进程
678            return handleSystemServerProcess(parsedArgs);
679        }
680
681        return null;
682    }

所以这儿首要逻辑就来到了handleSystemServerProcess办法,由该办法敞开体系服务进程的事务流程。

SystemServer事务流程剖析

咱们来看看首要逻辑的办法:

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
453       ...
500        } else {
501            ClassLoader cl = null;
502            if (systemServerClasspath != null) {
                    //创立PathClassLoader
503                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
504
505                Thread.currentThread().setContextClassLoader(cl);
506            }
                //初始化
511            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
512        }
513
514        /* should never reach here */
515    }

这儿首先是创立PathClassLoader,关于类加载,咱们后边文章细说,然后调用了ZygoteInit的zygoteInit函数:

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
852        if (RuntimeInit.DEBUG) {
853            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
854        }
855
856        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
857        RuntimeInit.redirectLogStreams();
858
859        RuntimeInit.commonInit();
            //这儿发动了Binder线程池
860        ZygoteInit.nativeZygoteInit();
            //初始化事务
861        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
862    }

这个办法中先发动了Binder线程池,然后开端进行体系服务进程的各种服务发动、办理作业。

这儿有个很要害的点,便是发动Binder线程池,关于Binder通讯咱们最了解的便是AIDL,而AIDL或者Binder的作业原理中服务端需求有一个线程池来处理客户端的恳求,这儿给出一张AIDL作业原理图:

framework | SystemServer进程流程分析

从上图咱们能够发现Binder通讯是根据C/S架构的,服务端处理数据会放入线程池中处理,所以每个需求运用Binder通讯的进程都有必要要创立Binder线程池

这也从另一个方面验证了一点,即上面发动进程的zygoteInit函数,都会创立一个用于Binder通讯的线程池,而上一篇文章所说的Zygote进程却没有这个,所以和Zygote进程通讯方式还是Socket,从SystemServer开端,体系服务进程和其他进程比方APP进程,便是运用Binder了

发动Binder线程池

关于Binder的规划非常复杂,触及知识点特别多,后续咱们仔细说,这儿先看看怎么发动Binder线程池。

nativeZygoteInit办法是一个native办法,因而咱们需求找到它的JNI文件,找到对应的C++文件。由Java文件界说的native办法,找到JNI办法是有技巧的,比方这儿的办法和类名分别是com.android.internal.os.ZygoteInit和nativeZygoteInit,所以它对应的JNI函数名便是把Java中的.换成_,即com_android_internal_os_ZygoteInit_nativeZygoteInit办法,该办法界说:

/frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
223 {
224     gCurRuntime->onZygoteInit();
225 }

这儿关于JNI类型的细节咱们不做讨论,咱们能够成功找到该上面本地办法对应的C++代码,当然这种按姓名的找法不一定对,由于Java中界说一个Native办法和其C/c++完成办法是经过JNI注册来做的一一对应联系,注册如下:

/frameworks/base/core/jni/AndroidRuntime.cpp
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
250 {
251     const JNINativeMethod methods[] = {
252         { "nativeZygoteInit", "()V",
253             (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
254     };
255     return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
256         methods, NELEM(methods));
257 }

关于jni注册的原理咱们后边JNI文章再说。

这儿咱们就只需求知道,在上面Java文件中界说的Native办法对应着com_android_internal_os_ZygoteInit_nativeZygoteInit即可。

在该办法中,gCurRuntime便是AppRuntime(AndroidRuntime子类)的目标,这儿是其成员办法:

/frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
92     {
93         sp<ProcessState> proc = ProcessState::self();
94         ALOGV("App process: starting thread pool.\n");
95         proc->startThreadPool();
96     }

这儿又调用了ProcessState的startThreadPool办法,这个ProcessState是Binder相关的类,这儿办法便是创立线程池,咱们不继续向下剖析了。

剖析这儿首要便是给大家说一下怎么找到JNI办法对应的C/C++办法,关于JNI原理后边文章细说。

SystemServer事务流程

在上面创立完Binder线程池后,会调用RuntimeInit中的applicationInit静态办法:

/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
291             ClassLoader classLoader) {
292        ...
310         return findStaticMain(args.startClass, args.startArgs, classLoader);
311     }

然后调用findStaticMain办法:

/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    private static Runnable findStaticMain(String className, String[] argv,
233             ClassLoader classLoader) {
234         Class<?> cl;
            //这儿的className为com.android.server.SystemServer
            //经过反射找到SystemServer的Java类
236         try {
237             cl = Class.forName(className, true, classLoader);
238         } catch (ClassNotFoundException ex) {
239             throw new RuntimeException(
240                     "Missing class when invoking static main " + className,
241                     ex);
242         }
243 
244         Method m;
            //找到SystemServer的main办法
245         try {
246             m = cl.getMethod("main", new Class[] { String[].class });
247         } catch (NoSuchMethodException ex) {
248             throw new RuntimeException(
249                     "Missing static main on " + className, ex);
250         } catch (SecurityException ex) {
251             throw new RuntimeException(
252                     "Problem getting static main on " + className, ex);
253         }
254 
255         int modifiers = m.getModifiers();
256         if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
257             throw new RuntimeException(
258                     "Main method is not public and static on " + className);
259         }
260 
261        //调用main办法
267         return new MethodAndArgsCaller(m, argv);
268     }

这儿咱们的调用流程就转移到了SystemServer.java的main办法:

/frameworks/base/services/java/com/android/server/SystemServer.java
    public static void main(String[] args) {
267         new SystemServer().run();
268     }
/frameworks/base/services/java/com/android/server/SystemServer.java
     private void run() {
278         try {
279            ...
                //创立消息Looper,用于线程间通讯
364             Looper.prepareMainLooper();
365 
366             //加载native库
367             System.loadLibrary("android_servers");
368 
371             performPendingShutdown();
372 
373             //创立体系的Context
374             createSystemContext();
375 
376             //创立体系服务办理类
377             mSystemServiceManager = new SystemServiceManager(mSystemContext);
378             mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
379             LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
380             // Prepare the thread pool for init tasks that can be parallelized
381             SystemServerInitThreadPool.get();
382         } finally {
383             traceEnd();  // InitBeforeStartServices
384         }
385 
386         //开端敞开各种服务
387         try {
388             traceBeginAndSlog("StartServices");
                //开端引导服务
389             startBootstrapServices();
                //开端中心服务
390             startCoreServices();
                //开端其他服务
391             startOtherServices();
392             SystemServerInitThreadPool.shutdown();
393         } catch (Throwable ex) {
394             Slog.e("System", "******************************************");
395             Slog.e("System", "************ Failure starting system services", ex);
396             throw ex;
397         } finally {
398             traceEnd();
399         }
                ...
401         //开端loop
416         Looper.loop();
417         throw new RuntimeException("Main thread loop unexpectedly exited");
418     }

这儿便是SystemServer进程所做的作业,首要包含:

  • 创立和循环Looper,这个用于线程间通讯,关于Handler知识,后边将会从使用层到底层仔细剖析;
  • 加载了动态库libandroid_servers.so,这儿是为了找到Native层的C/C++代码;
  • 创立体系Context,关于Context咱们后边文章独自剖析。
  • 创立了体系服务办理类实例mSystemServiceManager,它的类型是SystemServiceManager,用来创立、发动以及办理体系服务的一些生命周期事情

然后首要作业便是敞开各种服务,这儿的服务首要分为3类,一共加起来有好几十个,下面列举一些首要的服务:

引导服务 效果
Installer 体系装置APK时的一个服务类,发动完成Installer服务之后才能其他其他的体系服务
ActivityManagerService 负责四大组件的发动、切换和调度
PowerManagerService 核算体系中和Power相关的核算,然后决策体系应该怎么反响
LightsService 办理和显示背光LED
DisplayManagerService 用来办理所有显示设备
UserManagerService 多用户形式办理
SensorService 为消停供给各种感应服务
PackageManagerService 用来对APK进行装置、解析、删去、卸载等操作
中心服务 效果
DropBoxManagerService 用于生成和办理体系允许时的一些日志文件
Battery 办理电池的服务
UsageStatsService 搜集用户运用每一个APP的评率、时长等
其他服务 效果
CameraService 摄像头相关服务
AlarmManagerService 大局定时器办理服务
InputManagerService 办理输入事情
WindowManagerService 窗口办理服务
BluetoothService 蓝牙办理服务

等等

这些体系服务承担了Android体系的各种责任,经过相互合作让咱们能够运用和开发上层使用,这些服务特别多,也不用都需求掌握,一般都是了解其中重要的几个。

当然本章内容不是介绍这些服务,而是说服务发动,这儿以PowerManagerService和PackageManagerService来举例。

发动服务细节

这儿咱们先看PowerManagerService的发动流程,首先是SystemService.java中的startBootstrapServices()函数中调用:

/frameworks/base/services/java/com/android/server/SystemServer.java
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

这儿调用SystemServiceManager.java中的startService办法,该办法有好几个重载办法,先调用下面这个:

/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
//创立和发动一个体系服务,该服务有必要是SystemService的子类
    public <T extends SystemService> T startService(Class<T> serviceClass) {
83         ...
                //经过反射创立体系服务实例
93             final T service;
94             try {
95                 Constructor<T> constructor = serviceClass.getConstructor(Context.class);
96                 service = constructor.newInstance(mContext);
97             } catch (InstantiationException ex) {
98                 throw new RuntimeException("Failed to create service " + name
99                         + ": service could not be instantiated", ex);
100             } catch (IllegalAccessException ex) {
101                 throw new RuntimeException("Failed to create service " + name
102                         + ": service must have a public constructor with a Context argument", ex);
103             } catch (NoSuchMethodException ex) {
104                 throw new RuntimeException("Failed to create service " + name
105                         + ": service must have a public constructor with a Context argument", ex);
106             } catch (InvocationTargetException ex) {
107                 throw new RuntimeException("Failed to create service " + name
108                         + ": service constructor threw an exception", ex);
109             }
                //发动服务
111             startService(service);
112             return service;
113         } finally {
114             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
115         }
116     }

这儿代码比较简单便是经过反射创立其实例,这儿有必要注意一点便是所有体系服务都有必要是SystemServer.java的子类,然后这儿再调用另一个重载函数startService:

/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
     public void startService(@NonNull final SystemService service) {
             //注册该service
120         mServices.add(service);
122         long time = SystemClock.elapsedRealtime();
123         try {
                //敞开服务
124             service.onStart();
125         } catch (RuntimeException ex) {
126             throw new RuntimeException("Failed to start service " + service.getClass().getName()
127                     + ": onStart threw an exception", ex);
128         }
129         warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
130     }

这儿的mServices便是一个ArrayList,保存着需求接收响应事情的体系服务,然后便是调用其onStart()办法:

/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
         @Override
686     public void onStart() {
            //发布到Binder服务中
687         publishBinderService(Context.POWER_SERVICE, new BinderService());
688         publishLocalService(PowerManagerInternal.class, new LocalService());
689 
690         Watchdog.getInstance().addMonitor(this);
691         Watchdog.getInstance().addThread(mHandler);
692     }

这儿咱们来重点看一下这个发布到Binder服务中的操作,由于这个触及Binder通讯,先看一下这个BinderService是啥:

private final class BinderService extends IPowerManager.Stub

这儿的代码了解AIDL的应该知道,这儿会界说一个IPowerManager.aidl的长途接口,用于IPC,然后这儿的IPowerManager.Stub则是生成的Java类,完成了IBinder接口,是一个Binder目标,所以这儿发布到Binder服务中的是一个Binder实例,接着看一下publishBinderService办法:

/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
198     protected final void publishBinderService(String name, IBinder service) {
199         publishBinderService(name, service, false);
200     }
201 
205     protected final void publishBinderService(String name, IBinder service,
206             boolean allowIsolated) {
207         ServiceManager.addService(name, service, allowIsolated);
208     }

这儿终究会经过ServiceManager把刚刚那个Binder给增加进来,更多关于ServiceManager的内容,后边介绍Binder时再细说。

这儿给AIDL通讯简单画个时序示意图:

sequenceDiagram
SystemServer ->> PowerManagerService:创立、发动服务
PowerManagerService ->> PowerManagerService:new BinderService() 获取Binder目标
PowerManagerService ->> SystemServiceManager:publishBinderService() 传递Binder目标
SystemServiceManager ->> ServiceManager:addService 注册Binder
使用进程X ->> SystemServiceManager:想和PowerManagerService通讯
SystemServiceManager ->> 使用进程X:返回Binder引用
Note over 使用进程X,PowerManagerService:使用进程X和PowerManagerService经过Binder进行通讯

由上面图咱们可知能进行Binder跨进程通讯的条件还得需求注册和”中间人”人物

除了经过用mSystemServiceManager的startService发动体系服务外,还能够经过下面方式发动,咱们以PMS为例:

/frameworks/base/services/java/com/android/server/SystemServer.java
 mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
586                 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
 public static PackageManagerService main(Context context, Installer installer,
2347             boolean factoryTest, boolean onlyCore) {
2348        
2349         PackageManagerServiceCompilerMapping.checkProperties();
2350 
                //经过new创立目标
2351         PackageManagerService m = new PackageManagerService(context, installer,
2352                 factoryTest, onlyCore);
2353         m.enableSystemUserPackages();
2354         ServiceManager.addService("package", m);
2355         final PackageManagerNative pmn = m.new PackageManagerNative();
2356        
                //注册Binder
                ServiceManager.addService("package_native", pmn);
2357         return m;
2358     }

这儿能够直接调用体系服务的main函数来创立和发动体系服务,同样也必不可少地需求注册Binder到ServiceManager中。

总结

体系服务进程被创立后,先创立了Context、敞开Looper、加载so等常规操作,首要的作业如下:

  • 发动Binder线程池,为Binder服务做根底,由于Binder通讯需求线程池来处理恳求。
  • 创立SystemServiceManager,用于对体系服务进行创立、发动和生命周期办理。
  • 发动各种服务,在各种服务中都少不了注册Binder,为了经过Binder和其他进程通讯。

跟着Android体系代码的梳理,一方面逐渐了了解了各种规划的奇妙和新知识,一方面也发现很多技术债,比方前面的Linux、JNI、so库等技术,还有本章触及的Context、Looper等知识,这些知识很多之前都触及过,可是没有个体系了解和总结,总是感觉无法完全了解,还需求不断加油打破这些难点。

笔者水平有限,文中有问题,欢迎纠正。终究记录一下Flag。# 一个Android开发的学习Flag记录贴