SystemServer进程启动分析

在前面关于Zygote启动的文章分析过,Zygote进程启动后会去启动SystemServer进程,本篇就来分析下SystemServer启动流程。

//ZygoteInit.java
public static void main(String argv[]) {
    ....
	if (startSystemServer) {
            startSystemServer(abiList, socketName, zygoteServer);
        }
   }
//ZygoteInit.java
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.MethodAndArgsCaller, RuntimeException {

       //启动system server进程的一些参数
        /* Hardcoded command line to start the system server */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            //解析参数
            parsedArgs = new ZygoteConnection.Arguments(args);
            //fork子进程
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        }

        /* For child process */
    	//子进程也就是SystemServer进程会执行到这个分支
        if (pid == 0) {
			//SystemServer进程不需要要从父进程(zygote)继承来的ServerSocket
            zygoteServer.closeServerSocket();
            //执行子进程相关代码
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

startSystemServer主要干了3件事:

  • 设置了一些启动system server进程的参数,比如用户id,组id,还有进程创建后要执行的类com.android.server.SystemServer。
  • fork出SystemServe进程
  • 执行子进程相关代码,最终会执行com.android.server.SystemServer的main函数。

首先分析Zygote.forkSystemServer,看看是如何fork子进程的。

//Zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        int pid = nativeForkSystemServer(
                uid, gid, gids...);
        return pid;
    }

native private static int nativeForkSystemServer(int uid, int gid, int[] gids...);

调用到native层的com_android_internal_os_Zygote.cpp的nativeForkSystemServer方法。

//com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
        jlong effectiveCapabilities) {
    //调用了ForkAndSpecializeCommon方法
  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
                                      debug_flags, rlimits,
                                      permittedCapabilities, effectiveCapabilities,
                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
                                      NULL, NULL, NULL);
  return pid;
}

static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid...) {
  //直接通过fork函数来创建一个子进程
  pid_t pid = fork();
  //...
  return pid;
}

关于fork函数可以查看我的Linux博客,这样一个进程就创建出来了,接着分析handleSystemServerProcess。

//ZygoteInit.java
private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws Zygote.MethodAndArgsCaller {
    	//从启动进程的参数可知没有设置--invoke-with,因此parsedArgs.invokeWith为空
        if (parsedArgs.invokeWith != null) {
		
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

            }
            //走到这
            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    }

handleSystemServerProcess的代码不多,主要是创建了systemServer的类加载器,然后调用ZygoteInit.zygoteInit方法,把parsedArgs遗留的参数以及类加载器传进去了。

//ZygoteInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        //这个方法最终会启动当前进程的binder线程池,本篇暂不分析
        ZygoteInit.nativeZygoteInit();
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

接着调用了 RuntimeInit.applicationInit方法。

//RuntimeInit.java
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {

        final Arguments args;
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            return;
        }
		//调用了invokeStaticMain方法
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }


private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        Class<?> cl;
		//获取com.android.server.SystemServer的class对象,这个className就是之前参数配置的
        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
        }

        Method m;
        try {
            //获取SystemServer的main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        }

		//这个注释很有意思,所以我没删
        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
    	//抛出异常,并且把SystemServer的main方法和argv传进去了
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }

这个异常是在哪里捕获的呢?注释已经很清楚了ZygoteInit.main()方法。

public static void main(String argv[]) {
        try {
            if (startSystemServer) {
                startSystemServer(abiList, socketName, zygoteServer);
            }

        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
        
        }
    }

捕获了这个异常后就会调用它的run方法,为什么要这么干呢,主要是为了清除所有的堆栈帧,这样调用SystemServer的入口main方法时,之前的堆栈帧都会被清除,看起来更像一个入口函数,当然可能也有其他好处。继续往下分析:

//Zygote.java
public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                //直接调用了SystemServer的main方法
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } 
        }
    }

到这里新创建的进程就去执行SystemServer类的main方法了。

//SystemServer.java
public static void main(String[] args) {
    //调用了SystemServer类的run方法
        new SystemServer().run();
    }


private void run() {
        try {

            // Here we go!
            Slog.i(TAG, "Entered the Android system server!");
			//SystemServer的Looper消息循环
            Looper.prepareMainLooper();

            // Initialize native services.
            //加载动态库libandroid_servers.so
            System.loadLibrary("android_servers");

            // Initialize the system context.
            createSystemContext();

            // Create the system service manager.
            //创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        } 

        // Start services.
        try {
		//引导服务:ActivityManagerService、PowerMandiaoagerService、PackageManagerService等
            startBootstrapServices();
			//核心服务:BatteryService、UsageStatsService和WebViewUpdateService等
            startCoreServices();
			//其他服务:AlarmManagerService、VrManagerService等
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            throw ex;
        }

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

可以看到SystemServer的run方法,启动了很多系统服务,而系统根据服务的特性分为了三类。引导服务、核心服务以及其他服务。

到这里SystemServer的启动流程其实就分析完成了,SystemServer在启动时回去创建许多的系统服务,包括我们经常打交道的ActivityManagerService主要用来管理四大组件的生命周期调度、PowerManagerService 是设备电源管理的系统服务 、PackageManagerService 管理所有和 package 相关的工作,比如安装、卸载应用。

有些系统服务并不是通过SystemServiceManager来完成启动的。这里挑几个常见的系统服务看看是如何在SystemServer中被启动的。

//SystemServer.java
private void startBootstrapServices() {
       //启动了AMS
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();

        //启动了PowerManagerService
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

		//PKMS
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    
    	//把AMS加入到ServiceManager中
    	mActivityManagerService.setSystemProcess();

    }

SystemServiceManager的startService方法如下

//SystemServiceManager.java

//通过类名启动系统服务
public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } 
        return startService(serviceClass);
    }

//通过类名创建系统服务
public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                //直接通过反射创建了系统服务的实例
                service = constructor.newInstance(mContext);
            } 
			//然后调用startService方法把服务的实例传入
            startService(service);
            return service;
        } 
    }

public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
    	//直接调用了SystemService的onStart方法
        service.onStart();
    }

SystemServiceManager的startService很简单,通过反射创建实例,然后调用onStart方法。

而启动ActivityManagerService时传入了ActivityManagerService.Lifecycle.class

//ActivityManagerService.java
public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            //在构造方法中传入了创建了ActivityManagerService
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
            //调用ActivityManagerService的start方法,启动ActivityManagerService
            mService.start();
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }

创建并启动了ActivityManagerService之后会把他加入到ServiceManager中。

//ActivityManagerService.java
public void setSystemProcess() {
    	//把AMS的IBinder注册到ServiceManager中
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
    }

可以看到这里把服务注册到ServiceManager了,ServiceManager属于一个单独的进程,也是由init进程启动的,它的角色相当于服务的路由器(DNS)。当然了ServiceManager那边绑定的是服务名称和对应的handle值,不过,目前只需要简单理解通过这个方法把服务注册到ServiceManager,其他进程可以通过服务的名称来查询对应的服务就好了。

接着分析下PowerManagerService的启动注册,根据前面分析知道,调用startService传入PowerManagerService.class必然会创建它的实例,然后调用它的onStart方法。

//PowerManagerService.java
public void onStart() {
    //BinderService是PowerManagerService的内部类,继承自IPowerManager.Stub
        publishBinderService(Context.POWER_SERVICE, new BinderService());
    }

调用了publishBinderService,传入了BinderService实例,BinderService继承自IPowerManager.Stub,了解AIDL的一眼就看出来了吧。

这个publishBinderService是父类SystemService的方法。

//SystemService.java
protected final void publishBinderService(String name, IBinder service) {
        publishBinderService(name, service, false);
    }

protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
    //可以看到最终还是被添加到ServiceManager了
        ServiceManager.addService(name, service, allowIsolated);
    }

最后来看下PKMS的启动,它只是调用了PackageManagerService.main就完成了PackageManagerService的启动,其实本质还是一样的。

//PackageManagerService.java
public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        // Self-check for initial settings.
        PackageManagerServiceCompilerMapping.checkProperties();

        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);
        ServiceManager.addService("package", m);
        return m;
    }

是不是很简单,最终还是被注册到ServiceManager中。

finsh~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值