Android系统启动流程(三)SystemServer进程启动过程解析

上一篇我们分析了zygote进程的启动过程,其中有一个步骤是startSystemServer,这一篇就来详细分析一下system_server进程的启动过程。

1 Zygote中startSystemServer

frameworks/base/core/java/com/android/internal/os/ZygoteInit

private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        ...
        /* For child process */
        /**
         * 在子进程中启动systemServer进程
         */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            handleSystemServerProcess(parsedArgs);
        }
        return true;
    }

上面通过handleSystemServerProcess来启动应用程序进程,源码如下:


    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();
        
        if (parsedArgs.invokeWith != null) {
            
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = createSystemServerClassLoader(systemServerClasspath,
                                                   parsedArgs.targetSdkVersion);

                Thread.currentThread().setContextClassLoader(cl);
            }
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    }

首先关闭了从zygote进复制的无用的socket, 然后在handleSystemServerProcess的最后调用了RuntimeInit.zygoteInit方法,我们跟进去看:

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java


public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
        redirectLogStreams();

        commonInit();
        /**启动Binder线程池*/
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv, classLoader);
    }
    

RuntimeInit.zygoteInit方法调用到了nativeZygoteInit这个native层方法,这个方法是用来启动Binder线程池的,我们接下来看代码是如何执行的。


2 NativeZygoteInit - 启动Binder线程池

nativeZygoteInit函数对用的JNI文件如下:

frameworks/base/core/jni/AndroidRuntime.cpp

/*
 * JNI registration.
 */
static const JNINativeMethod gMethods[] = {android
    { "nativeFinishInit", "()V",
        (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
    { "nativeZygoteInit", "()V",
        (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
    { "nativeSetExitWithoutCleanup", "(Z)V",
        (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
};

通过上面JNI的gMethods数组,看出nativeZygoteInit函数对应的是JNI文件AndroidRuntime.cpp的com_android_internal_os_RuntimeInit_nativeZygoteInit函数,

static AndroidRuntime* gCurRuntime = NULL;
...
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

因为这里gCurRuntime是AndroidRuntime类型的指针,这里调用到了AppRuntime的onZygoteInit函数,代码如下所示。

frameworks/base/cmds/app_process/app_main.cpp

 virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

上面看到最终是调用了startThreadPool()方法,启动了一个Binder线程池,用来与其它进程进行通信。所以上面RuntimeInit.nativeZygoteInit函数就是为了启动Binder线程池。接下来我们看RuntimeInit.applicationInit函数。

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        
        final Arguments args;
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            // let the process exit
            return;
        }

        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

接着调用到了invokeStaticMain函数:

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;
        try {
        	// 1 
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
        	// 2
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }
        // 3
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

在注释1处通过反射生成一个class对象,这里的className是前面参数传递过来的com.android.server.SystemServer,在注释2处通过反射找到SystemServer的main函数,注释3处直接抛出了一个MethodAndArgsCaller的异常,这个异常在哪里被处理的呢?我们回头看下ZygoteInit的main函数的最后:

    public static void main(String argv[]) {
		try {
		...
       		runSelectLoop(abiList);

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

从上面看到调用了caller.run(),也就是调用了MethodAndArgsCaller.run方法,源码如下

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 {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }

看到调用的是mMethod.invoke,即最终就调用到了SystemServer.main函数,下面我们进行分析。


3 SystemServer进程解析

frameworks/base/services/java/com/android/server/SystemServer.java

	public static void main(String[] args) {
	    new SystemServer().run();
	}
	
	private void run() {

			Looper.prepareMainLooper();

            // Initialize native services.
            System.loadLibrary("android_servers");

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();
            
            /**1 创建SystemContext*/
            // Initialize the system context.
            createSystemContext();

            // Create the system service manager.
            /**2 创建SystemServiceManager*/
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }

        // Start services.
        try {
        	
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
            startBootstrapServices();//3 启动引导服务
            startCoreServices();//4 启动核心服务
            startOtherServices();//5 启动其它服务
        } catch (Throwable ex) {
            throw ex;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

run函数主要完成了以下几个工作:

  • 注释1处创建createSystemContext。
  • 注释2处创建SystemServiceManager,它负责启动,创建和管理系统服务。内部存储了各种启动的大约80多种服务。
  • 注释3处启动了引导服务,比如ActivityManagerService、PowerManagerService、PackageManagerService。
  • 注释4处启动了核心服务,如BatteryService、UsageStatsService和WebViewUpdateService。
  • 注释5处则启动了CameraService、AlarmManagerService、VrManagerService等服务。

这些服务的父类基本都为SystemService, 系统将服务分为了三个类别,引导服务,核心服务和其它服务,下面通过表格列举其中一些服务:

引导服务作用
Installer系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务
ActivityManagerService负责四大组件的启动、切换、调度。
PowerManagerService计算系统中和Power相关的计算,然后决策系统应该如何反应
DisplayManagerService用来管理所有显示设备
UserManagerService多用户模式管理
SensorService为系统提供各种感应器服务
PackageManagerService用来对apk进行安装、解析、删除、卸载等等操作
LightsService管理和显示背光LED
核心服务
BatteryService管理电池相关的服务
UsageStatsService收集用户使用每一个APP的频率、使用时常
WebViewUpdateServiceWebView更新服务
其他服务
CameraService摄像头相关服务
AlarmManagerService全局定时器管理服务
InputManagerService管理输入事件
WindowManagerService窗口管理服务
VrManagerServiceVR模式管理服务
BluetoothService蓝牙管理服务
NotificationManagerService通知管理服务
DeviceStorageMonitorService存储相关管理服务
LocationManagerService定位管理服务
AudioService音频相关管理服务
SystemServiceManager.startService

比如要启动Installer, 调用如下:

Installer installer = mSystemServiceManager.startService(Installer.class);

我们进入SystemServiceManager.startService的源码,如下:

public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
            	// 1 
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            }
            ...
			// 2
            mServices.add(service);

			// 3
            try {
                service.onStart();
            } catch (RuntimeException ex) {
                throw new RuntimeException("Failed to start service " + name
                        + ": onStart threw an exception", ex);
            }
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }

在注释1处通过反射获取SystemService,这里是Installer。在注释2处将Installer添加到mServices集合中,mServices集合是用来存储SystemService集合的。注释3调用service.onStart()启动并且返回service。

除了这种启动方式外,像PackageManagerService是通过main函数启动的,如下:

public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        // Self-check for initial settings.
        /**(1)检查Package编译相关系统属性*/
        PackageManagerServiceCompilerMapping.checkProperties();

        /**(2)调用PackageManagerService构造方法, 同学们可以参考【PKMS构造方法】 */
        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);

        /**(3)启用部分应用, 服务于多用户场景*/
        m.enableSystemUserPackages();

        /**(4)往ServiceManager中注册”package”*/
        ServiceManager.addService("package", m);
        return m;
    }

上面注释4处的ServiceManager用来管理系统中的各种Service,用于系统C/S架构中的Binder机制通信。客户端想要使用某个服务,需要到ServiceManager中查询,然后建立通信。


SystemServer进程总结
  • 启动Binder线程池建立进程间通信。
  • 创建SystemServiceManager,它用于对系统服务进行创建、启动和生命周期管理。
  • 启动三类大约80多种系统服务。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 12 SystemServer启动流程如下: 1. 引导加载:系统启动时,先加载引导程序,进行硬件初始化、内核加载等操作。 2. Zygote 进程启动:Zygote 是 Android 系统中的一个特殊进程,负责孵化其他应用进程。Zygote 进程会预加载一些常用的类和资源,以加快应用的启动速度。 3. SystemServer 进程启动:Zygote 进程会 fork 出 SystemServer 进程,该进程Android 系统中的核心服务进程。SystemServer 进程负责启动和管理系统级别的服务,例如 ActivityManagerService、PackageManagerService、WindowManagerService 等。 4. SystemServer 初始化:SystemServer 进程启动后,会进行一系列的初始化操作。首先会创建 Looper 线程,用于接收消息并处理各个服务的初始化工作。然后依次创建各个系统服务,并调用它们的启动方法。 5. 启动系统服务:SystemServer 进程会按照一定顺序启动各个系统服务。每个系统服务都有自己的初始化流程,例如 PackageManagerService 会加载应用程序列表、数据目录等;ActivityManagerService 会初始化进程间通信机制等。 6. 启动应用进程:在系统服务启动完成后,SystemServer 进程会通过 Zygote 孵化出其他应用进程。应用进程会根据 AndroidManifest.xml 中的配置进行初始化,包括创建 Application、加载资源等。 总结来说,Android 12 SystemServer启动流程包括引导加载、Zygote 进程启动、SystemServer 进程启动、SystemServer 初始化、启动系统服务和启动应用进程等步骤。这些步骤都是为了在系统启动时提供必要的服务和资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值