今天主要分析Android启动流程,重点是system_server相关知识。

一、Android系统启动流程

Android正常启动流程如下:
Step1 系统加电,执行bootloader。Bootloader负责初始化软件运行所需要的最小硬件环境,最后加载内核到内存。
Step2 内核加载进内存后,将首先进入内核引导阶段,在内核引导阶段的最后,调用start_kenel进入内核启动阶段。start_kenel最终启动用户空间的init程序。
Step3 init程序负责解析init.rc配置文件,开启系统守护进程。两个最重要的守护进程是zygote进程和ServiceManager,zygote是Android启动的第一个Dalvik虚拟机,ServiceManager是Binder通讯的基础。
Step4 zygote虚拟机启动子进程system_server,在system_server中开启了核心系统服务,并将系统服务添加到ServiceManager中,然后系统进入SystemReady状态。
Step5 在SystemReady状态,ActivityManagerService与zygote中的socket通信,通过zygote启动home应用,进入系统桌面。

从Step3开始,init启动后,上层的实现。
Step1 init启动的核心Daemon服务包括Android的第一个Dalvik虚拟机zygote。
Step2 zygote定义一个socket,用于接受ActivityManagerService启动应用的请求。
Step3 zygote通过fork系统调用创建system_server进程
Step4 在system_server进程中,将会启动系统核心服务以及其他服务。
Step5 系统服务启动后会注册到ServiceManager中,用于Binder通信。
Step6 ActivityManagerService进入systemReady状态。
Step7 在systemReady状态,ActivityManagerService会与zygote的Socket通信,请求启动Home。
Step8 zygote收到AMS的连接请求后,执行runSelectLoopMode处理请求。
Step9 zygote处理请求会通过forkAndSpecialize启动新的应用进程,并最终启动Home。

二、system_server启动过程

在Step3,系统会创建system_server,下面开始分析system_server创建过程。
系统在预加载了共享资源后,编开始启动system_server进程,system_server是理解framework层的基础。Android中所有的系统服务都由它启动,它的异常会导致zygote的自杀重启,这样整个java就崩溃了。
System_server的启动入口是startSystemServer方法,位于frameworks/base/core/java/com/android/internal/os/ZygoteInit.java。
在ZygoteInit的main函数,调用了方法startSystemServer。

  public static void main(String argv[]) {        ...        String socketName = "zygote";        ...        try {                       ...           if (startSystemServer) {                startSystemServer(abiList, socketName);            }              ....

分析startSystemServer方法:

 /**     * Prepare the arguments and fork for the system server process.     */    private static boolean startSystemServer(String abiList, String socketName)            throws MethodAndArgsCaller, RuntimeException {        long capabilities = posixCapabilitiesAsBits(            OsConstants.CAP_IPC_LOCK,            OsConstants.CAP_KILL,            OsConstants.CAP_NET_ADMIN,            OsConstants.CAP_NET_BIND_SERVICE,            OsConstants.CAP_NET_BROADCAST,            OsConstants.CAP_NET_RAW,            OsConstants.CAP_SYS_MODULE,            OsConstants.CAP_SYS_NICE,            OsConstants.CAP_SYS_RESOURCE,            OsConstants.CAP_SYS_TIME,            OsConstants.CAP_SYS_TTY_CONFIG        );        /* Containers run without this capability, so avoid setting it in that case */        if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {            capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);        }        /* Hardcoded command line to start the system server */        /*  设置启动system_server的命令行参数 */        String args[] = {            "--setuid=1000", //设置用户的ID为1000,这个UID代表系统权限            "--setgid=1000",            /// M: ANR mechanism for system_server add shell(2000) group to access            ///    /sys/kernel/debug/tracing/tracing_on            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,2000," +                "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 {            //将数组分解成Arguments类型的对象,过程很简单            parsedArgs = new ZygoteConnection.Arguments(args);            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);            /* Request to fork the system server process */            //调用系统fork函数创建子进程,这个子进程就是sysytem_server            pid = Zygote.forkSystemServer(                    parsedArgs.uid, parsedArgs.gid,                    parsedArgs.gids,                    parsedArgs.debugFlags,                    null,                    parsedArgs.permittedCapabilities,                    parsedArgs.effectiveCapabilities);        } catch (IllegalArgumentException ex) {            throw new RuntimeException(ex);        }        /* For child process */        //pid为0说明在子进程system_server中        if (pid == 0) {            if (hasSecondZygote(abiList)) {                waitForSecondaryZygote(socketName);            }            //在子进程system_server中调用了handleSystemServerProcess方法            handleSystemServerProcess(parsedArgs);        }        //在父进程中返回        return true;    }

到这里,zygote做了第一次分裂,forck出系统服务的总管system_server进程,这个过程分为以下两个重要的步骤:
1)、通过forkSystemServer创建system_server子进程。
2)、在子进程中调用handleSystemServerProcess方法。

2.1 通过forkSystemServer创建system_server子进程
启动system_server的第一步便是调用zygote的system_server方法,在该方法内部将调用Native方法nativeForkSystemServer,来完成启动system_server进程的任务。nativeForkSystemServer的JNI层实现方法位于frameworks/base/core/jni/com_android_internal_os_Zygote.cpp中,方法名为com_android_internal_os_Zygote_nativeForkSystemServer()。

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) {            //间接调用了ForkAndSpecializeCommom() 函数  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,                                      debug_flags, rlimits,                                      permittedCapabilities, effectiveCapabilities,                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,                                      NULL, NULL);  if (pid > 0) {//pid>0,则是在system_server的父进程zygote中      // The zygote process checks whether the child process has died or not.      ALOGI("System server process %d has been created", pid);      gSystemServerPid = pid;//在虚拟机中记录system_server的进程ID      // There is a slight window that the system server process has crashed      // but it went unnoticed because we haven't published its pid yet. So      // we recheck here just to make sure that all is well.      int status;      //退出前,重新检查sysem_server进程是否有异常,如果异常退出,      //则zygote直接自杀,因为在zygote的服务项中配置了onrestart这个*option,      //所以zogote自杀后,init进程会重新启动它      if (waitpid(pid, &status, WNOHANG) == pid) {          ALOGE("System server process %d has died. Restarting Zygote!", pid);          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");      }  }  return pid;}

在这里,系统会检查system_server进程是否启动成功,如果启动失败,将导致zygote重启。system_server负责构建系统服务,如果启动失败,Android系统也就无法启动,所以必须重启zygote、因此Dalvik_dalvik_system_Zygote_forkSystemServer方法的功能分成两部分:
1)启动system_server进程。
2)监控system_server进程的启动结果。

2.1.1 启动system_server进程
这部分功能由ForkAndSpecializeCommon()函数实现,位于本类中,

static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,                                     jint debug_flags, jobjectArray javaRlimits,                                     jlong permittedCapabilities, jlong effectiveCapabilities,                                     jint mount_external,                                     jstring java_se_info, jstring java_se_name,                                     bool is_system_server, jintArray fdsToClose,                                     jstring instructionSet, jstring dataDir){                                     ......//省略                                     //设置信号处理函数                                     SetSigChldHandler();                                     //调用fork()函数                                     pid_t pid = fork();                                     if (pid == 0){                                         ......//子进程                                     }else if(pid > 0) {                                         ......//父进程处理                                     }                                     return pid;}

ForkAndSpecializeCommon函数通过fork()系统函数创建子进程system_server,并在创建system_server前做了重要工作:注册信号处理函数。该信号处理函数的作用就是代表子线程退出的信号。在setSigChldHandler()函数:

// Configures the SIGCHLD handler for the zygote process. This is configured// very late, because earlier in the runtime we may fork() and exec()// other processes, and we want to waitpid() for those rather than// have them be harvested immediately.//// This ends up being called repeatedly before each fork(), but there's// no real harm in that.static void SetSigChldHandler() {    //这里是非常通用的Linux注册信号处理函数的流程,调用系统函数sigaction()处理    //SIGCHLD信号,具体的处理函数是SigChldHandler。SIGCHLD信号是子进程退出信号  struct sigaction sa;  memset(&sa, 0, sizeof(sa));  sa.sa_handler = SigChldHandler;  int err = sigaction(SIGCHLD, &sa, NULL);  if (err < 0) {    ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));  }}

SetSigChldHandler注册了信号处理函数sigChldHandler,处理的信号便是SIGCHLD,代表子进程退出信号。

2.1.2 监控system_server进程的启动结果
当子进程退出时,由SigChldHandler处理该信号,接下来分析sigchldHandler处理SIGCHLD信号。

// This signal handler is for zygote mode, since the zygote must reap its childrenstatic void SigChldHandler(int /*signal_number*/) {  pid_t pid;  int status;  // It's necessary to save and restore the errno during this function.  // Since errno is stored per thread, changing it here modifies the errno  // on the thread on which this signal handler executes. If a signal occurs  // between a call and an errno check, it's possible to get the errno set  // here.  // See b/23572286 for extra information.  int saved_errno = errno;//调用系统函数waitpid等待子进程退出//第一个参数-1表示等待任何子进程//第二个参数status用于收集子进程退出时的状态//第三个参数WNOHANG表示如果没有子进程退出,不需要阻塞  while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {     // Log process-death status that we care about.  In general it is     // not safe to call LOG(...) from a signal handler because of     // possible reentrancy.  However, we know a priori that the     // current implementation of LOG() is safe to call from a SIGCHLD     // handler in the zygote process.  If the LOG() implementation     // changes its locking strategy or its use of syscalls within the     // lazy-init critical section, its use here may become unsafe.    if (WIFEXITED(status)) {      if (WEXITSTATUS(status)) {        ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));      }    } else if (WIFSIGNALED(status)) {      if (WTERMSIG(status) != SIGKILL) {        ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));      }      if (WCOREDUMP(status)) {        ALOGI("Process %d dumped core.", pid);      }    }    // If the just-crashed process is the system_server, bring down zygote    // so that it is restarted by init and system server will be restarted    // from there.    if (pid == gSystemServerPid) {      ALOGE("Exit zygote because system server (%d) has terminated", pid);      //如果退出的是system_server进程,zygote重启,SIGKILL是自杀信号。      //虽然zygote自杀了,但是init进程会负责救活它。      kill(getpid(), SIGKILL);    }  }

从forkSystemServer函数的执行过程可以看出:zygote创建system_server进程是十分谨慎的,不但在创建之初判断system_server是否退出,在创建后还专门注册信号处理函数监控system_server的运行状态。如果system_server出现意外,zygote也会自杀,导致整个java世界崩溃。
接下来分析fork出system_server后的处理。

2.2 在子进程中调用handleSystemServerProcess方法
system_server进程启动之后,便开始调用handleSystemServerProcess方法,该方法位于ZygoteInit.java中,代码如下:

    /**     * Finish remaining work for the newly forked system server process.     */    private static void handleSystemServerProcess(            ZygoteConnection.Arguments parsedArgs)            throws ZygoteInit.MethodAndArgsCaller {        // 关闭之前fork操作时,从zygote继承下来的socket        closeServerSocket();        // set umask to 0077 so new files and directories will default to owner-only permissions.        Os.umask(S_IRWXG | S_IRWXO);        if (parsedArgs.niceName != null) {            Process.setArgV0(parsedArgs.niceName);        }        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");        if (systemServerClasspath != null) {            performSystemServerDexOpt(systemServerClasspath);        }        // 根据invokeWith参数,执行一个shell命令        if (parsedArgs.invokeWith != null) {            String[] args = parsedArgs.remainingArgs;            // If we have a non-null system server class path, we'll have to duplicate the            // existing arguments and append the classpath to it. ART will handle the classpath            // correctly when we exec a new process.            if (systemServerClasspath != null) {                String[] amendedArgs = new String[args.length + 2];                amendedArgs[0] = "-cp";                amendedArgs[1] = systemServerClasspath;                System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);            }            WrapperInit.execApplication(parsedArgs.invokeWith,                    parsedArgs.niceName, parsedArgs.targetSdkVersion,                    VMRuntime.getCurrentInstructionSet(), null, args);        } else {            ClassLoader cl = null;            if (systemServerClasspath != null) {                cl = createSystemServerClassLoader(systemServerClasspath,                                                   parsedArgs.targetSdkVersion);                Thread.currentThread().setContextClassLoader(cl);            }            /*             * Pass the remaining arguments to SystemServer.             */             //调用zygoteInit方法,传入参数            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);        }        /* should never reach here */    }

system_server生成之后,迅速进入工作状态,执行handleSystemServerProcess。在该方法中,首先做了一些清理和初始化工作,接着调用RuntimeInit.zygoteInit()方法。
RuntimeInit.java位于frameworks\base\core\java\com\android\internal\os\RuntimeInit.java,

/**     * The main function called when started through the zygote process. This     * could be unified with main(), if the native code in nativeFinishInit()     * were rationalized with Zygote startup.

* * Current recognized args: *

    *
  • [--] <start class name> <args> *
* * @param targetSdkVersion target SDK version * @param argv arg strings */
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(); nativeZygoteInit(); applicationInit(targetSdkVersion, argv, classLoader); }

zygoteInit封装了对四个方法的调用,对应四个步骤试下 不同的初始化操作,接下来分析四步。

2.2.1 redirectLogStrreams() 方法重定向标准I/O操作
redirectLogStreams()方法重定向Java标准I/O操作到Android日志系统。

   /**     * Redirect System.out and System.err to the Android log.     */    public static void redirectLogStreams() {        System.out.close();        System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));        System.err.close();        System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));    }

2.2.2 commonInit() 方法初始化通用设置

    private static final void commonInit() {        if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");        /* set default handler; this applies to all threads in the VM */        //设置未不会异常的默认处理函数        Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());        /*         * Install a TimezoneGetter subclass for ZoneInfo.db         */         //获取persist.sys.timezone 属性        TimezoneGetter.setInstance(new TimezoneGetter() {            @Override            public String getId() {                return SystemProperties.get("persist.sys.timezone");            }        });        TimeZone.setDefault(null);        /*         * Sets handler for java.util.logging to use Android log facilities.         * The odd "new instance-and-then-throw-away" is a mirror of how         * the "java.util.logging.config.class" system property works. We         * can't use the system property here since the logger has almost         * certainly already been initialized.         */         //Android Log配置        LogManager.getLogManager().reset();        new AndroidConfig();        /*         * Sets the default HTTP User-Agent used by HttpURLConnection.         */         //默认的HTTP User-Agent,用于HTTP连接        String userAgent = getDefaultUserAgent();        System.setProperty("http.agent", userAgent);        /*         * Wire socket tagging to traffic stats.         */        NetworkManagementSocketTagger.install();//网络相关        /*         * If we're running in an emulator launched with "-trace", put the         * VM into emulator trace profiling mode so that the user can hit         * F9/F10 at any time to capture traces.  This has performance         * consequences, so it's not something you want to do always.         */         //模拟器上面的trace调试        String trace = SystemProperties.get("ro.kernel.android.tracing");        if (trace.equals("1")) {            Slog.i(TAG, "NOTE: emulator trace profiling enabled");            Debug.enableEmulatorTraceOutput();        }

2.2.3 onZygoteInit 方法开启Binder通信
nativeZygoteInit是一个Native方法,其JNI实现方法位于frameworks\base\core\jni\AndroidRuntime.cpp,方法名为com_android_internal_os_RuntimeInit_nativeZygoteInit,具体代码:

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

onZygoteInit开启了sysytem_serve的Binder通道。

2.2.4 invokeStaticMain方法抛出异常

这样,system_server进程已经基本启动完成,之后system_server进程会启动系统核心服务,以及其他服务。

更多相关文章

  1. original-package
  2. 【Android】设置tabhost位于底部的三种方法
  3. Android平台上sqllite 简介
  4. Android(安卓)属性动画原理与DataBinding
  5. Android线程优先级设置方法
  6. Android(安卓)AsyncTask
  7. Android核心分析(21)----Android应用框架之AndroidApplication
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. 超酷的计步器APP(一)——炫酷功能实现,自定
  2. Android(安卓)中的危险权限详细整理
  3. Android(安卓)版本更新签名冲突的问题以
  4. 谁能想到,Android外包工作三年,能入职某大
  5. Android应用《撕开美女衣服》的实现过程
  6. 国产神器天语Android双核手机W700线下赏
  7. Supernote 讓你在華碩的平板上做出不少好
  8. Android的px、dp和sp等单位的区别详解
  9. Android收发UDP报文详解 及 优雅解决接收
  10. android一步一步实现视频客户端app(一)