Android 10.0 系统启动之SystemServer进程-[Android取经之路]

 

摘要:上一节讲解了Zygote进程的整个启动流程。Zygote是所有应用的鼻祖。SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。Zygote fork的第一个进程就是SystemServer,其在手机中的进程名为 system_server。

 

阅读本文大约需要花费50分钟。

文章的内容主要还是从源码进行分析,虽然又臭又长,但是如果想要学习Android系统源码,这是必要走的路,没有捷径。

相对于碎片学习,我更倾向于静下心来花费1个小时认真的学习一段内容。

文章首发微信公众号:IngresGe

专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析

[Android取经之路] 系列文章:

《系统启动篇》

  1. Android系统架构
  2. Android是怎么启动的
  3. Android 10.0系统启动之init进程
  4. Android10.0系统启动之Zygote进程
  5. Android 10.0 系统启动之SystemServer进程
  6. Android 10.0 系统服务之ActivityMnagerService
  7. Android10.0系统启动之Launcher(桌面)启动流程
  8. Android10.0应用进程创建过程以及Zygote的fork流程
  9. Android 10.0 PackageManagerService(一)工作原理及启动流程
  10. Android 10.0 PackageManagerService(二)权限扫描
  11. Android 10.0 PackageManagerService(三)APK扫描
  12. Android 10.0 PackageManagerService(四)APK安装流程

《日志系统篇》

  1. Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
  2. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
  3. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
  4. Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​

《Binder通信原理》

  1. Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
  2. Android10.0 Binder通信原理(二)-Binder入门篇
  3. Android10.0 Binder通信原理(三)-ServiceManager篇
  4. Android10.0 Binder通信原理(四)-Native-C\C++实例分析
  5. Android10.0 Binder通信原理(五)-Binder驱动分析
  6. Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
  7. Android10.0 Binder通信原理(七)-Framework binder示例
  8. Android10.0 Binder通信原理(八)-Framework层分析
  9. Android10.0 Binder通信原理(九)-AIDL Binder示例
  10. Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式​​​​​​​​​​​​​​
  11. Android10.0 Binder通信原理(十一)-Binder总结

 

1.概述

上一节讲解了Zygote进程的整个启动流程。Zygote是所有应用的鼻祖。SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。Zygote fork的第一个进程就是SystemServer,其在手机中的进程名为 system_server。

system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等80多个核心系统服务。这些服务以不同的线程方式存在于system_server这个进程中。

接下来,就让我们透过Android系统源码一起来分析一下SystemServer的整个启动过程。

 

2.核心源码

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

/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/serverSystemServiceManager.java
/frameworks/base/services/core/java/com/android/ServiceThread.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

/frameworks/base/core/java/android/app/ActivityThread.java
/frameworks/base/core/java/android/app/LoadedApk.java
/frameworks/base/core/java/android/app/ContextImpl.java

/frameworks/base/core/jni/AndroidRuntime.cpp
/frameworks/base/core/jni/com_android_internal_os_ZygoteInit.cpp
/frameworks/base/cmds/app_process/app_main.cpp

3.架构

3.1 架构图

    SystemServer 被Zygote进程fork出来后,用来创建ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等90多个核心系统服务

 Android 10.0 系统启动之SystemServer进程-[Android取经之路]_第1张图片

3.2 服务启动

 SystemServer思维导图

Android 10.0 系统启动之SystemServer进程-[Android取经之路]_第2张图片

4. 源码分析

4.1 SystemServer fork流程分析

 Android 10.0 系统启动之SystemServer进程-[Android取经之路]_第3张图片

4.1.1 [ZygoteInit.java] main()

说明:Zygote进程,通过fork()函数,最终孵化出system_server的进程,通过反射的方法启动

SystemServer.java的main()方法

源码:

public static void main(String argv[]) {
	ZygoteServer zygoteServer = null;
    ...
	try {
		zygoteServer = new ZygoteServer(isPrimaryZygote);
		if (startSystemServer) {
			//fork system_server
			Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

			// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
			// child (system_server) process.
			if (r != null) {
				r.run(); //启动SystemServer.java的main()
				return; //Android 8.0之前是通过抛异常的方式来启动,这里是直接return出去,用来清空栈,提高栈帧利用率
			}
		}
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }
	if (caller != null) {
        caller.run();
    }
	...
}

 

4.1.2[ZygoteInit.java] forkSystemServer()

说明:准备参数,用来进行system_server的fork,从参数可知,pid=1000,gid=1000,进程名nick-name=system_server

当有两个Zygote进程时,需要等待第二个Zygote创建完成。由于fork时会拷贝socket,因此,在fork出system_server进程后,

需要关闭Zygote原有的socket

源码:

private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
    ......
    //参数准备,uid和gid都是为1000
    String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                    + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs = null;
    int pid;
    try {
        //将上面准备的参数,按照ZygoteArguments的风格进行封装
        parsedArgs = new ZygoteArguments(args);
        Zygote.applyDebuggerSystemProperty(parsedArgs);
        Zygote.applyInvokeWithSystemProperty(parsedArgs);

        //通过fork"分裂"出子进程system_server
        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    //进入子进程system_server
    if (pid == 0) {
        // 处理32_64和64_32的情况
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);  //需要等待第二个Zygote创建完成
        }

        // fork时会copy socket,Zygote原有的socket需要关闭
        zygoteServer.closeServerSocket();
        // system server进程处理自己的工作
        return handleSystemServerProcess(parsedArgs);
    }
    return null;
}

4.1.3 [Zygote.java] forkSystemServer()

说明:这里的nativeForkSystemServer()最终是通过JNI,调用Nativate C空间的com_android_internal_os_Zygote_nativeForkSystemServer()

来fork system_server

源码:

 

public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    ZygoteHooks.preFork();
    // Resets nice priority for zygote process.
    resetNicePriority();
    //调用native的方法来fork system_server
    //最终调用native的方法:com_android_internal_os_Zygote_nativeForkSystemServer
    int pid = nativeForkSystemServer(
            uid, gid, gids, runtimeFlags, rlimits,
            permittedCapabilities, effectiveCapabilities);
    // Enable tracing as soon as we enter the system_server.
    if (pid == 0) {
        Trace.setTracingEnabled(true, runtimeFlags);
    }
    ZygoteHooks.postForkCommon();
    return pid;
}

[com_android_internal_os_Zygote.cpp]

说明:JNI注册的映射关系

static const JNINativeMethod gMethods[] = {
    { "nativeForkSystemServer", "(II[II[[IJJ)I",
      (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
}

 

4.1.4[com_android_internal_os_Zygote.cpp]

com_android_internal_os_Zygote_nativeForkSystemServer()

说明:通过 SpecializeCommon进行fork,pid返回0时,表示当前为system_server子进程

当pid >0 时,是进入父进程,即Zygote进程,通过waitpid 的WNOHANG 非阻塞方式来监控

system_server进程挂掉,如果挂掉后重启Zygote进程。

现在使用的Android系统大部分情况下是64位的,会存在两个Zygote,当system_server挂掉后,

只启动Zygote64这个父进程

源码:

static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
        jlong effective_capabilities) {


  pid_t pid = ForkCommon(env, true,
                         fds_to_close,
                         fds_to_ignore);
  if (pid == 0) {
      //进入子进程
      SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                       permitted_capabilities, effective_capabilities,
                       MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
                       false, nullptr, nullptr);
  } else if (pid > 0) {
      //进入父进程,即zygote进程
      ALOGI("System server process %d has been created", pid);

      int status;
	  //用waitpid函数获取状态发生变化的子进程pid
	  //waitpid的标记为WNOHANG,即非阻塞,返回为正值就说明有进程挂掉了
      if (waitpid(pid, &status, WNOHANG) == pid) {
		  //当system_server进程死亡后,重启zygote进程
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
      }
	  ...
  }
  return pid;
}

4.1.5 [com_android_internal_os_Zygote.cpp] ForkCommon

说明:从Zygote孵化出一个进程的使用程序

源码:

 

static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                        const std::vector& fds_to_close,
                        const std::vector& fds_to_ignore) {
  //设置子进程的signal
  SetSignalHandlers();

  //在fork的过程中,临时锁住SIGCHLD
  BlockSignal(SIGCHLD, fail_fn);

  //fork子进程,采用copy on write方式,这里执行一次,会返回两次
  //pid=0 表示Zygote  fork SystemServer这个子进程成功
  //pid > 0 表示SystemServer 的真正的PID
  pid_t pid = fork();

  if (pid == 0) {
     //进入子进程
    // The child process.
    PreApplicationInit();

    // 关闭并清除文件描述符
    // Clean up any descriptors which must be closed immediately
    DetachDescriptors(env, fds_to_close, fail_fn);
	...
  } else {
    ALOGD("Forked child process %d", pid);
  }

  //fork结束,解锁
  UnblockSignal(SIGCHLD, fail_fn);

  return pid;
}

4.1.6 [Zygcom_android_internal_os_Zygoteote.cpp] SpecializeCommon

说明:system_server进程的一些调度配置

源码:

 

static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
                             jint runtime_flags, jobjectArray rlimits,
                             jlong permitted_capabilities, jlong effective_capabilities,
                             jint mount_external, jstring managed_se_info,
                             jstring managed_nice_name, bool is_system_server,
                             bool is_child_zygote, jstring managed_instruction_set,
                             jstring managed_app_data_dir) {
  ...
  bool use_native_bridge = !is_system_server &&
                           instruction_set.has_value() &&
                           android::NativeBridgeAvailable() &&
                           android::NeedsNativeBridge(instruction_set.value().c_str());

  if (!is_system_server && getuid() == 0) {
    //对于非system_server子进程,则创建进程组
    const int rc = createProcessGroup(uid, getpid());
    if (rc == -EROFS) {
      ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
    } else if (rc != 0) {
      ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
    }
  }

  SetGids(env, gids, fail_fn);  //设置设置group
  SetRLimits(env, rlimits, fail_fn); //设置资源limit

  if (use_native_bridge) {
    // Due to the logic behind use_native_bridge we know that both app_data_dir
    // and instruction_set contain values.
    android::PreInitializeNativeBridge(app_data_dir.value().c_str(),
                                       instruction_set.value().c_str());
  }

  if (setresgid(gid, gid, gid) == -1) {
    fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno)));
  }
   ...
   //selinux上下文
  if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
    fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed",
                         uid, is_system_server, se_info_ptr, nice_name_ptr));
  }

  //设置线程名为system_server,方便调试
  if (nice_name.has_value()) {
    SetThreadName(nice_name.value());
  } else if (is_system_server) {
    SetThreadName("system_server");
  }

  // Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers).
  //设置子进程的signal信号处理函数为默认函数
  UnsetChldSignalHandler();

  if (is_system_server) {
   
    //对应  Zygote.java 的callPostForkSystemServerHooks()
    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks);
    if (env->ExceptionCheck()) {
      fail_fn("Error calling post fork system server hooks.");
    }

	//对应ZygoteInit.java 的 createSystemServerClassLoader()
	//预取系统服务器的类加载器。这样做是为了尽早地绑定适当的系统服务器selinux域。
    env->CallStaticVoidMethod(gZygoteInitClass, gCreateSystemServerClassLoader);
    if (env->ExceptionCheck()) {
      // Be robust here. The Java code will attempt to create the classloader
      // at a later point (but may not have rights to use AoT artifacts).
      env->ExceptionClear();
    }
	...
  }

   //等价于调用zygote.java 的callPostForkChildHooks()
  env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
                            is_system_server, is_child_zygote, managed_instruction_set);

  if (env->ExceptionCheck()) {
    fail_fn("Error calling post fork hooks.");
  }
}

4.1.7 [ZygoteInit.java] handleSystemServerProcess

说明:创建类加载器,并赋予当前线程,其中环境变量SYSTEMSERVERCLASSPATH,主要是service.jar、ethernet-service.jar和wifi-service.jar这三个jar包

export SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar

源码:

 

private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {

    if (parsedArgs.mNiceName != null) {
        Process.setArgV0(parsedArgs.mNiceName); //设置当前进程名为"system_server"
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
       //执行dex优化操作
        if (performSystemServerDexOpt(systemServerClasspath)) {
            sCachedSystemServerClassLoader = null;
        }
		...
    }

    if (parsedArgs.mInvokeWith != null) {
        String[] args = parsedArgs.mRemainingArgs;
		//如果我们有一个非空系统服务器类路径,我们将不得不复制现有的参数并将类路径附加到它。
		//当我们执行一个新进程时,ART将正确地处理类路径。
        if (systemServerClasspath != null) {
            String[] amendedArgs = new String[args.length + 2];
            amendedArgs[0] = "-cp";
            amendedArgs[1] = systemServerClasspath;
            System.arraycopy(args, 0, amendedArgs, 2, args.length);
            args = amendedArgs;
        }

        //启动应用进程
        WrapperInit.execApplication(parsedArgs.mInvokeWith,
                parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                VMRuntime.getCurrentInstructionSet(), null, args);

        throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
    } else {
        // 创建类加载器,并赋予当前线程
        createSystemServerClassLoader();
        ClassLoader cl = sCachedSystemServerClassLoader;
        if (cl != null) {
            Thread.currentThread().setContextClassLoader(cl);
        }

        //system_server进入此分支
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                parsedArgs.mRemainingArgs, cl);
    }
}

4.1.8[ZygoteInit.java] zygoteInit

说明:基础配置,并进行应用初始化,返回对象

源码:

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
    RuntimeInit.redirectLogStreams();  //重定向log输出

    RuntimeInit.commonInit(); //通用的一些初始化
    ZygoteInit.nativeZygoteInit(); // zygote初始化
    // 应用初始化
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

4.1.9[RuntimeInit.java] commonInit

说明:配置log、时区、http userAgent等基础信息

源码:

 

protected static final void commonInit() {
	LoggingHandler loggingHandler = new LoggingHandler();
    
    // 设置默认的未捕捉异常处理方法
    RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler);
    Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));

    // 设置时区,通过属性读出中国时区为"Asia/Shanghai"
    RuntimeHooks.setTimeZoneIdSupplier(() -> SystemProperties.get("persist.sys.timezone"));

    //重置log配置
    LogManager.getLogManager().reset();
    new AndroidConfig();

    //设置默认的HTTP User-agent格式,用于 HttpURLConnection
    String userAgent = getDefaultUserAgent();
    System.setProperty("http.agent", userAgent);

    /*
     * Wire socket tagging to traffic stats.
     */
    //设置socket的tag,用于网络流量统计
    NetworkManagementSocketTagger.install();
	...
}

4.1.10[ZygoteInit.java] nativeZygoteInit

说明:nativeZygoteInit 通过反射,进入com_android_internal_os_ZygoteInit_nativeZygoteInit

源码:

[AndroidRuntime.cpp]

int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
    const JNINativeMethod methods[] = {
        { "nativeZygoteInit", "()V",
            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
        methods, NELEM(methods));
}

gCurRuntime = this;
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    //此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的
    gCurRuntime->onZygoteInit();
}

[app_main.cpp]
virtual void onZygoteInit()
{
    sp proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool(); //启动新binder线程
}

 

4.1.11[RuntimeInit.java] applicationInit

说明:通过参数解析,得到args.startClass = com.android.server.SystemServer

源码:

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {

    //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用
    nativeSetExitWithoutCleanup(true);

    // We want to be fairly aggressive about heap utilization, to avoid
    // holding on to a lot of memory that isn't needed.
    
    //设置虚拟机的内存利用率参数值为0.75
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

    final Arguments args = new Arguments(argv);  //解析参数
	...
    // Remaining arguments are passed to the start class's static main
    //调用startClass的static方法 main() 
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

4.1.12 [RuntimeInit.java] findStaticMain

说明:拿到SystemServer的main()方法,并返回 MethodAndArgsCaller()对象

源码:

 

protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class cl;

    try {
		//拿到com.android.server.SystemServer 的类对象
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }

    Method m;
    try {
        //得到SystemServer的main()方法,
        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);
    }

    //把MethodAndArgsCaller的对象返回给ZygoteInit.main()。这样做好处是能清空栈帧,提高栈帧利用率
	//清除了设置进程所需的所有堆栈帧
    return new MethodAndArgsCaller(m, argv);
}

4.1.13[RuntimeInit.java] MethodAndArgsCaller

说明:最终在ZygoteInit.java的main(),调用这里的run()来启动SystemServer.java的main(),真正进入SystemServer进程

源码:

 

static class MethodAndArgsCaller 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);
        } 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);
        }
    }
}

4.2 SystemServer 启动后的流程

 Android 10.0 系统启动之SystemServer进程-[Android取经之路]_第4张图片

 

4.2.1[SystemServer.java] main

说明:main函数由Zygote进程 fork后运行,作用是new 一个SystemServer对象,再调用该对象的run()方法

源码:

public static void main(String[] args) {
    //new 一个SystemServer对象,再调用该对象的run()方法
    new SystemServer().run();
}

4.2.2 [SystemServer.java] run

说明:先初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等候再启动服务,启动引导服务、核心服务和其他服务

源码:

  

private void run() {
    try {
        traceBeginAndSlog("InitBeforeStartServices");

        // Record the process start information in sys props.
        //从属性中读取system_server进程的一些信息
        SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
        SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));
        SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));

        EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
                mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);


        //如果一个设备的时钟是在1970年之前(0年之前),
        //那么很多api 都会因为处理负数而崩溃,尤其是java.io.File#setLastModified
        //我把把时间设置为1970
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

        //如果时区不存在,设置时区为GMT
        String timezoneProperty = SystemProperties.get("persist.sys.timezone");
        if (timezoneProperty == null || timezoneProperty.isEmpty()) {
            Slog.w(TAG, "Timezone not set; setting to GMT.");
            SystemProperties.set("persist.sys.timezone", "GMT");
        }

        //变更虚拟机的库文件,对于Android 10.0默认采用的是libart.so
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        // Mmmmmm... more memory!
        //清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间
        VMRuntime.getRuntime().clearGrowthLimit();
		...
        //系统服务器必须一直运行,所以它需要尽可能高效地使用内存
        //设置内存的可能有效使用率为0.8
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);


        //一些设备依赖于运行时指纹生成,所以在进一步启动之前,请确保我们已经定义了它。
        Build.ensureFingerprintProperty();

        //访问环境变量前,需要明确地指定用户
        //在system_server中,任何传入的包都应该被解除,以避免抛出BadParcelableException。
        BaseBundle.setShouldDefuse(true);

        //在system_server中,当打包异常时,信息需要包含堆栈跟踪
        Parcel.setStackTraceParceling(true);

        //确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority)
        BinderInternal.disableBackgroundScheduling(true);

        //设置system_server中binder线程的最大数量,最大值为31
        BinderInternal.setMaxThreads(sMaxBinderThreads);

        //准备主线程lopper,即在当前线程运行
        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        //加载android_servers.so库,初始化native service
        System.loadLibrary("android_servers");

        // Debug builds - allow heap profiling.
        //如果是Debug版本,允许堆内存分析
        if (Build.IS_DEBUGGABLE) {
            initZygoteChildHeapProfiling();
        }

        //检测上次关机过程是否失败,这个调用可能不会返回
        performPendingShutdown();

        //初始化系统上下文
        createSystemContext();

        //创建系统服务管理--SystemServiceManager
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        //将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        //为可以并行化的init任务准备线程池
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }

    // Start services.
    //启动服务
    try {
        traceBeginAndSlog("StartServices");
        startBootstrapServices();   // 启动引导服务
        startCoreServices();        // 启动核心服务
        startOtherServices();       // 启动其他服务
        SystemServerInitThreadPool.shutdown(); //停止线程池
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }

    //为当前的虚拟机初始化VmPolicy
    StrictMode.initVmDefaults(null);
	...
    // Loop forever.
    //死循环执行
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

4.2.3[SystemServer.java] performPendingShutdown

说明:检测上次关机过程是否失败,这个调用可能不会返回

源码:

 

private void performPendingShutdown() {
    final String shutdownAction = SystemProperties.get(
            ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
    if (shutdownAction != null && shutdownAction.length() > 0) {
        boolean reboot = (shutdownAction.charAt(0) == '1');

        final String reason;
        if (shutdownAction.length() > 1) {
            reason = shutdownAction.substring(1, shutdownAction.length());
        } else {
            reason = null;
        }

        //如果需要重新启动才能应用更新,一定要确保uncrypt在需要时正确执行。
        //如果'/cache/recovery/block.map'还没有创建,停止重新启动,它肯定会失败,
        //并有机会捕获一个bugreport时,这仍然是可行的。
        if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {
            File packageFile = new File(UNCRYPT_PACKAGE_FILE);
            if (packageFile.exists()) {
                String filename = null;
                try {
                    filename = FileUtils.readTextFile(packageFile, 0, null);
                } catch (IOException e) {
                    Slog.e(TAG, "Error reading uncrypt package file", e);
                }

                if (filename != null && filename.startsWith("/data")) {
                    if (!new File(BLOCK_MAP_FILE).exists()) {
                        Slog.e(TAG, "Can't find block map file, uncrypt failed or " +
                                "unexpected runtime restart?");
                        return;
                    }
                }
            }
        }
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    //当属性sys.shutdown.requested的值为1时,会重启
                    //当属性的值不为空,且不为1时,会关机
                    ShutdownThread.rebootOrShutdown(null, reboot, reason);
                }
            }
        };

        // ShutdownThread must run on a looper capable of displaying the UI.
        //ShutdownThread必须在一个能够显示UI的looper上运行
        //即UI线程启动ShutdownThread的rebootOrShutdown
        Message msg = Message.obtain(UiThread.getHandler(), runnable);
        msg.setAsynchronous(true);
        UiThread.getHandler().sendMessage(msg);

    }
}

4.2.4[SystemServer.java] createSystemContext

说明:初始化系统上下文, 该过程会创建对象有ActivityThread,Instrumentation, ContextImpl,LoadedApk,Application

源码:

private void createSystemContext() {
    //创建system_server进程的上下文信息
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    //设置主题
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

    //获取systemui上下文信息,并设置主题
    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

4.2.5[SystemServer.java] startBootstrapServices

说明:用于启动系统Boot级服务,有ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService, sensor服务.

源码:

 

private void startBootstrapServices() {
    traceBeginAndSlog("StartWatchdog");
    //启动watchdog
    //尽早启动watchdog,如果在早起启动时发生死锁,我们可以让system_server
    //崩溃,从而进行详细分析
    final Watchdog watchdog = Watchdog.getInstance();
    watchdog.start();
    traceEnd();

...
    //添加PLATFORM_COMPAT_SERVICE,Platform compat服务被ActivityManagerService、PackageManagerService
    //以及将来可能出现的其他服务使用。
    traceBeginAndSlog("PlatformCompat");
    ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE,
            new PlatformCompat(mSystemContext));
    traceEnd();

    //阻塞等待installd完成启动,以便有机会创建具有适当权限的关键目录,如/data/user。
    //我们需要在初始化其他服务之前完成此任务。
    traceBeginAndSlog("StartInstaller");
    Installer installer = mSystemServiceManager.startService(Installer.class);
    traceEnd();
...
    //启动服务ActivityManagerService,并为其设置mSystemServiceManager和installer
    traceBeginAndSlog("StartActivityManager");
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService();
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    mWindowManagerGlobalLock = atm.getGlobalLock();
    traceEnd();

    //启动服务PowerManagerService
    //Power manager需要尽早启动,因为其他服务需要它。
    //本机守护进程可能正在监视它的注册,
    //因此它必须准备好立即处理传入的绑定器调用(包括能够验证这些调用的权限)
。
    traceBeginAndSlog("StartPowerManager");
    mPowerManagerService = mSystemServiceManager.startService(
PowerManagerService.class);
    traceEnd();

...
    //初始化power management
    traceBeginAndSlog("InitPowerManagement");
    mActivityManagerService.initPowerManagement();
    traceEnd();

    //启动recovery system,以防需要重新启动
    traceBeginAndSlog("StartRecoverySystemService");
    mSystemServiceManager.startService(RecoverySystemService.class);
    traceEnd();
...
    //启动服务LightsService
    //管理led和显示背光,所以我们需要它来打开显示
    traceBeginAndSlog("StartLightsService");
    mSystemServiceManager.startService(LightsService.class);
    traceEnd();
...
    //启动服务DisplayManagerService
    //显示管理器需要在包管理器之前提供显示指标
    traceBeginAndSlog("StartDisplayManager");
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
    traceEnd();

    // Boot Phases: Phase100: 在初始化package manager之前,需要默认的显示.
    traceBeginAndSlog("WaitForDisplay");
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    traceEnd();

    //当设备正在加密时,仅运行核心
    String cryptState = VoldProperties.decrypt().orElse("");
    if (ENCRYPTING_STATE.equals(cryptState)) {
        Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
        mOnlyCore = true;
    } else if (ENCRYPTED_STATE.equals(cryptState)) {
        Slog.w(TAG, "Device encrypted - only parsing core apps");
        mOnlyCore = true;
    }
...
    //启动服务PackageManagerService
    traceBeginAndSlog("StartPackageManagerService");
    try {
        Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    } finally {
        Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
    }
...
    //启动服务UserManagerService,新建目录/data/user/
    traceBeginAndSlog("StartUserManagerService");
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
    traceEnd();

    // Set up the Application instance for the system process and get  started.
    //为系统进程设置应用程序实例并开始。
    //设置AMS
    traceBeginAndSlog("SetSystemProcess");
    mActivityManagerService.setSystemProcess();
    traceEnd();

    //使用一个ActivityManager实例完成watchdog设置并监听重启,
//只有在ActivityManagerService作为一个系统进程正确启动后才能这样做
    traceBeginAndSlog("InitWatchdog");
    watchdog.init(mSystemContext, mActivityManagerService);
    traceEnd();

     //传感器服务需要访问包管理器服务、app ops服务和权限服务,
    //因此我们在它们之后启动它。
    //在单独的线程中启动传感器服务。在使用它之前应该检查完成情况。
    mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
        TimingsTraceLog traceLog = new TimingsTraceLog(
                SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.
TRACE_TAG_SYSTEM_SERVER);
        traceLog.traceBegin(START_SENSOR_SERVICE);
        startSensorService(); //启动传感器服务
        traceLog.traceEnd();
    }, START_SENSOR_SERVICE);
}

4.2.6[SystemServer.java] startCoreServices

说明:启动核心服务BatteryService,UsageStatsService,WebViewUpdateService、BugreportManagerService、GpuService等

源码:

private void startCoreServices() {
    //启动服务BatteryService,用于统计电池电量,需要LightService.
    mSystemServiceManager.startService(BatteryService.class);

    //启动服务UsageStatsService,用于统计应用使用情况
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));

    //启动服务WebViewUpdateService
    //跟踪可更新的WebView是否处于就绪状态,并监视更新安装
    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
        mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    }

    //启动CachedDeviceStateService,跟踪和缓存设备状态
    mSystemServiceManager.startService(CachedDeviceStateService.class);

    //启动BinderCallsStatsService, 跟踪在绑定器调用中花费的cpu时间
    traceBeginAndSlog("StartBinderCallsStatsService");
    mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);
    traceEnd();

    //启动LooperStatsService,跟踪处理程序中处理消息所花费的时间。
    traceBeginAndSlog("StartLooperStatsService");
    mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);
    traceEnd();

    //启动RollbackManagerService,管理apk回滚
    mSystemServiceManager.startService(RollbackManagerService.class);

    //启动BugreportManagerService,捕获bugreports的服务
    mSystemServiceManager.startService(BugreportManagerService.class);

    //启动GpuService,为GPU和GPU驱动程序提供服务。
    mSystemServiceManager.startService(GpuService.class);
}

 

4.2.7[SystemServer.java] startOtherServices

说明:启动其他的服务,开始处理一大堆尚未重构和整理的东西,这里的服务太多,大体启动过程类似,就不详细说明

源码:

private void startOtherServices() {
	...
    //启动TelecomLoaderService,通话相关核心服务
    mSystemServiceManager.startService(TelecomLoaderService.class);

    //启动TelephonyRegistry
    telephonyRegistry = new TelephonyRegistry(context);
    ServiceManager.addService("telephony.registry", telephonyRegistry);
	...
	//启动AlarmManagerService,时钟管理
	mSystemServiceManager.startService(new AlarmManagerService(context));
	...
	//启动InputManagerService
	inputManager = new InputManagerService(context);
	ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
            /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
	...
	inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
    inputManager.start();
	...
	//Phase480:在接收到此启动阶段后,服务可以获得锁设置数据
    mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);

    //Phase500:在接收到这个启动阶段之后,服务可以安全地调用核心系统服务,
    //如PowerManager或PackageManager。
    mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
	
	mActivityManagerService.systemReady(() -> {
        //Phase550:在接收到此引导阶段后,服务可以广播意图。
        mSystemServiceManager.startBootPhase(
                SystemService.PHASE_ACTIVITY_MANAGER_READY);

		//Phase600:在接收到这个启动阶段后,服务可以启动/绑定到第三方应用程序。
        //此时,应用程序将能够对服务进行绑定调用。
        mSystemServiceManager.startBootPhase(
        SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
	}
}

 

5.服务启动分析

  服务启动流程如下,从阶段0到阶段1000,一共8个阶段。

 Android 10.0 系统启动之SystemServer进程-[Android取经之路]_第5张图片

其中PHASE_BOOT_COMPLETED=1000,该阶段是发生在Boot完成和home应用启动完毕。系统服务更倾向于监听该阶段,而不是注册广播ACTION_BOOT_COMPLETED,从而降低系统延迟。

 

5.1 PHASE 0:

  说明:startBootstrapServices() 启动引导级服务

       主要启动以下10个服务:

  • Installer
  • DeviceIdentifiersPolicyService
  • UriGrantsManagerService
  • ActivityTaskManagerService
  • ActivityManagerService
  • PowerManagerService
  • ThermalManagerService
  • RecoverySystemService
  • LightsService
  • DisplayManagerService

 

启动完后,进入PHASE_WAIT_FOR_DEFAULT_DISPLAY=100, 即Phase100阶段

源码:

       ...
    //1.启动DeviceIdentifiersPolicyService
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);

    //2.启动UriGrantsManagerService
    mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);

    //3.启动ActivityTaskManagerService
    atm = mSystemServiceManager.startService(
                ActivityTaskManagerService.Lifecycle.class).getService();

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

    //5.启动ThermalManagerService
    mSystemServiceManager.startService(ThermalManagerService.class);

    //6.启动RecoverySystemService
    mSystemServiceManager.startService(RecoverySystemService.class);

    //7.启动LightsService
    mSystemServiceManager.startService(LightsService.class);

    //8.启动DisplayManagerService
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
    
    //执行回调函数 onBootPhase,把PHASE_WAIT_FOR_DEFAULT_DISPLAY=100, 传入各个service的 onBootPhase
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
       ...
}

5.2 PHASE 100  (阶段100):

定义:public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;

说明: 启动阶段-Boot Phase, 该阶段需要等待Display有默认显示

             进入阶段PHASE_WAIT_FOR_DEFAULT_DISPLAY=100回调服务: onBootPhase(100)

流程:startBootPhase(100) -> onBootPhase(100)

从以下源码可以看到这里遍历了一下服务列表,然后回调到各服务的 onBootPhase() 方法中了。每个服务的onBootPhase()处理都不相同,这里不详细分析

源码:

public void startBootPhase(final int phase) {
        ...
        mCurrentPhase = phase;
        ...
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
            ...
            try {
                service.onBootPhase(mCurrentPhase); // 轮训前面加过的service,把phase加入服务回调
            } catch (Exception ex) {
                ...
            }
            ...
        }
        ...
    }

 

创建以下80多个服务

  • BatteryService
  • UsageStatsService
  • WebViewUpdateService
  • CachedDeviceStateService
  • BinderCallsStatsService
  • LooperStatsService
  • RollbackManagerService
  • BugreportManagerService
  • GpuService
  • ....

5.3 PHASE 480  (阶段480):

定义:public static final int PHASE_LOCK_SETTINGS_READY = 480;

说明: 该阶段后, 服务可以获取到锁屏设置的数据了

               480到500之间没有任何操作,直接进入500

 

5.4 PHASE 500  (阶段500):

定义:public static final int PHASE_SYSTEM_SERVICES_READY = 500;

说明:该阶段后,服务可以安全地调用核心系统服务,比如PowerManager或PackageManager。

        启动以下两个服务:

  •  PermissionPolicyService
  •  eviceSpecificServices

 

5.5 PHASE 520  (阶段520):

定义:public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;

说明:在接收到这个引导阶段之后,服务可以安全地调用特定于设备的服务。

       告诉AMS可以运行第三方代码,Making services ready

       mActivityManagerService.systemReady()

 

5.6 PHASE 550  (阶段550):

定义:public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

说明:该阶段后,服务可以接收到广播Intents

       AMS启动native crash监控,启动SystemUI,其余服务调用systemReady()

       1) AMS启动native crash监控:

mActivityManagerService.startObservingNativeCrashes();

         2)  启动systemUI:

              startSystemUi()

        3) 其余服务调用systemReady():

  •        networkManagementF.systemReady()
  •        ipSecServiceF.systemReady();
  •        networkStatsF.systemReady();
  •        connectivityF.systemReady();
  •        networkPolicyF.systemReady(networkPolicyInitReadySignal);

 

5.7 PHASE 600  (阶段600):

定义:public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

说明:该阶段后,服务可以启动/绑定到第三方应用程序。此时,应用程序将能够对服务进行绑定调用。

               各种服务调用systemRunning方法:

  •                locationF.systemRunning();
  •                countryDetectorF.systemRunning();
  •                networkTimeUpdaterF.systemRunning();
  •                inputManagerF.systemRunning();
  •                telephonyRegistryF.systemRunning();
  •                mediaRouterF.systemRunning();
  •                mmsServiceF.systemRunning();
  •                incident.systemRunning();
  •                touchEventDispatchServiceF.systemRunning();

 

5.8 PHASE 1000 (阶段1000):

定义:public static final int PHASE_BOOT_COMPLETED = 1000;

说明: 该阶段后,服务可以允许用户与设备交互。此阶段在引导完成且主应用程序启动时发生。

             系统服务可能更倾向于监听此阶段,而不是为完成的操作注册广播接收器,以减少总体延迟。

               在经过一系列流程,再调用AMS.finishBooting()时,则进入阶段Phase1000。

               到此,系统服务启动阶段完成就绪,system_server进程启动完成则进入Looper.loop()状态,随时待命,等待消息队列MessageQueue中的消息到来,则马上进入执行状态。

 

6.服务分类

system_server进程启动的服务,从源码角度划分为引导服务、核心服务、其他服务3类。

引导服务 Boot Service (10个):

核心服务 Core Service(9个):

 

其他服务 Other Service(70个+):

 Android 10.0 系统启动之SystemServer进程-[Android取经之路]_第6张图片

7.总结

  • Zygote启动后fork的第一个进程为SystemServer,在手机中的进程别名为"system_server",主要用来启动系统中的服务
  • .Zygote fork后,进入SystemServer的main()
  • SystemServer在启动过程中,先初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等候再启动服务
  • 启动的服务分为 引导服务(Boot Service)、核心服务(Core Service)和其他服务(Other Service)三大类,共90多个服务
  • SystemServer在启动服务前,会尝试与Zygote建立Socket通信,通信成功后才去启动服务
  • 启动的服务都单独运行在SystemServer的各自线程中,同属于SystemServer进程

 

下一节我们来一起看看ActivityManagerService---AMS 服务是如何启动的。欢迎关注我,谢谢!

微信公众号:IngresGe

Android 10.0 系统启动之SystemServer进程-[Android取经之路]_第7张图片

你可能感兴趣的:(Android取经之路,#,1.系统启动)