每天一篇系列:
强化知识体系,查漏补缺。
欢迎指正,共同学习!

Android终端从断电到上电开始,历经了诸如fastboot,boot,kernel,system等流程,不同Android设备可能有些不同,网上对启动流程的总结大致如下:

图片来源于网上

其中Init是Android系统的第一个进程,也是这个文章分析的起点。
Android系统从Init开始,init.c的main函数:

int main(int argc, char **argv){...INFO("property init\n");    property_load_boot_defaults();    INFO("reading config file\n");    init_parse_config_file("/init.rc");    action_for_each_trigger("early-init", action_add_queue_tail);    queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");    queue_builtin_action(keychord_init_action, "keychord_init");    queue_builtin_action(console_init_action, "console_init");    /* execute all the boot actions to get us started */    action_for_each_trigger("init", action_add_queue_tail);    /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random     * wasn't ready immediately after wait_for_coldboot_done     */    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");    queue_builtin_action(property_service_init_action, "property_service_init");    queue_builtin_action(signal_init_action, "signal_init");    /* Don't mount filesystems or start core system services if in charger mode. */    if (is_charger) {        action_for_each_trigger("charger", action_add_queue_tail);    } else {        action_for_each_trigger("late-init", action_add_queue_tail);    }    ...   for(;;) {        int nr, i, timeout = -1;        execute_one_command();        restart_processes();        if (!property_set_fd_init && get_property_set_fd() > 0) {            ufds[fd_count].fd = get_property_set_fd();            ufds[fd_count].events = POLLIN;            ufds[fd_count].revents = 0;            fd_count++;            property_set_fd_init = 1;        }        if (!signal_fd_init && get_signal_fd() > 0) {            ufds[fd_count].fd = get_signal_fd();            ufds[fd_count].events = POLLIN;            ufds[fd_count].revents = 0;            fd_count++;            signal_fd_init = 1;        }        if (!keychord_fd_init && get_keychord_fd() > 0) {            ufds[fd_count].fd = get_keychord_fd();            ufds[fd_count].events = POLLIN;            ufds[fd_count].revents = 0;            fd_count++;            keychord_fd_init = 1;        }        if (process_needs_restart) {            timeout = (process_needs_restart - gettime()) * 1000;            if (timeout < 0)                timeout = 0;        }        if (!action_queue_empty() || cur_action)            timeout = 0;#if BOOTCHART        if (bootchart_count > 0) {            if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)                timeout = BOOTCHART_POLLING_MS;            if (bootchart_step() < 0 || --bootchart_count == 0) {                bootchart_finish();                bootchart_count = 0;            }        }#endif        nr = poll(ufds, fd_count, timeout);        if (nr <= 0)            continue;        for (i = 0; i < fd_count; i++) {            if (ufds[i].revents & POLLIN) {                if (ufds[i].fd == get_property_set_fd())                    handle_property_set_fd();                else if (ufds[i].fd == get_keychord_fd())                    handle_keychord();                else if (ufds[i].fd == get_signal_fd())                    handle_signal();            }        }    }    return 0;}

在main里面主要解析了init.*.rc文件,对SECTION,OPTION,COMMAND。
在解析rc文件时,区分了early-init,init,early-boot,boot四个阶段,其次就是Service的启动。
在init.rc中的有一个COMMAND为class_start default,对应着启动zygote进程。

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server    class main    socket zygote stream 660 root system    onrestart write /sys/android_power/request_state wake    onrestart write /sys/power/state on    onrestart restart media    onrestart restart netd

zygote在service_start函数中通过fork和execve共同创建。
然后初始化了Properties服务相关的内容,其中涉及到mmap共享内存,最大可以记录247条Properties。

zygote对应的原型是app_process,其源码是App_main.cpp:

int main(int argc, char* const argv[]){ ... while (i < argc) {        const char* arg = argv[i++];        if (strcmp(arg, "--zygote") == 0) {            zygote = true;            niceName = ZYGOTE_NICE_NAME;        } else if (strcmp(arg, "--start-system-server") == 0) {            startSystemServer = true;        } else if (strcmp(arg, "--application") == 0) {            application = true;        } else if (strncmp(arg, "--nice-name=", 12) == 0) {            niceName.setTo(arg + 12);        } else if (strncmp(arg, "--", 2) != 0) {            className.setTo(arg);            break;        } else {            --i;            break;        }    }    ...    if (zygote) {        runtime.start("com.android.internal.os.ZygoteInit", args);    } else if (className) {        runtime.start("com.android.internal.os.RuntimeInit", args);    } else {        fprintf(stderr, "Error: no class name or --zygote supplied.\n");        app_usage();        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");        return 10;    }}

使用AndroidRuntime.cpp去创建一个JavaVM虚拟机,加载JNI,配置运行环境等。然后通过JNI的反射机制,去调用com.android.internal.os.ZygoteInit的main函数。到这里就完成了从init.rc到AndroidRuntime直到Java的调用,到Java后的第一函数就是ZygoteInit的main函数。
在Zygote孵化进程中,处理startSystemServer的启动:

    private static boolean startSystemServer(String abiList, String socketName)            throws MethodAndArgsCaller, RuntimeException {...     try {            parsedArgs = new ZygoteConnection.Arguments(args);            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);            /* Request to fork the system server process */            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 */        if (pid == 0) {            if (hasSecondZygote(abiList)) {                waitForSecondaryZygote(socketName);            }            handleSystemServerProcess(parsedArgs);        }        return true;    }

在这个处理中forkSystemServer孵化出SystemServer进程,并最终会调用到SystemServer中的load1和load2流程,其中分为:

       // Start services.        try {            startBootstrapServices();            startCoreServices();            startOtherServices();        } catch (Throwable ex) {            Slog.e("System", "******************************************");            Slog.e("System", "************ Failure starting system services", ex);            throw ex;        }

把服务大致分成了三类,预启动服务类、核心服务类以及其他服务类。到这里可以看到这些Service还是运行在SystemServer的进程里面。也就是说服务运行在system_process里。

BootstrapServices是包含了几个在启动核心服务之前准备好的服务类:

private void startBootstrapServices() {        // Wait for installd to finish starting up so that it has a chance to        // create critical directories such as /data/user with the appropriate        // permissions.  We need this to complete before we initialize other services.        mInstaller = mSystemServiceManager.startService(Installer.class);        // Activity manager runs the show.        mActivityManagerService = mSystemServiceManager.startService(                ActivityManagerService.Lifecycle.class).getService();        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);        // Power manager needs to be started early because other services need it.        // Native daemons may be watching for it to be registered so it must be ready        // to handle incoming binder calls immediately (including being able to verify        // the permissions for those calls).        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);        // Now that the power manager has been started, let the activity manager        // initialize power management features.        mActivityManagerService.initPowerManagement();        // Display manager is needed to provide display metrics before package manager        // starts up.        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);        // We need the default display before we can initialize the package manager.        mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);        // Only run "core" apps if we're encrypting the device.        String cryptState = SystemProperties.get("vold.decrypt");        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;        }        // Start the package manager.        Slog.i(TAG, "Package Manager");        mPackageManagerService = PackageManagerService.main(mSystemContext, mInstaller,                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);        mFirstBoot = mPackageManagerService.isFirstBoot();        mPackageManager = mSystemContext.getPackageManager();        Slog.i(TAG, "User Service");        ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());        // Initialize attribute cache used to cache resources from packages.        AttributeCache.init(mSystemContext);        // Set up the Application instance for the system process and get started.        mActivityManagerService.setSystemProcess();    }

CoreServices包含了几个核心服务类的启动:

    /**     * Starts some essential services that are not tangled up in the bootstrap process.     */    private void startCoreServices() {        // Manages LEDs and display backlight.        mSystemServiceManager.startService(LightsService.class);        // Tracks the battery level.  Requires LightService.        mSystemServiceManager.startService(BatteryService.class);        // Tracks application usage stats.        mSystemServiceManager.startService(UsageStatsService.class);        mActivityManagerService.setUsageStatsManager(                LocalServices.getService(UsageStatsManagerInternal.class));        // Tracks whether the updatable WebView is in a ready state and watches for update installs.        mSystemServiceManager.startService(WebViewUpdateService.class);    }

在SystemServer中,各种服务准备之前必须保证ActivityManagerService已经准备好,可见AMS的重要性:

    private void startOtherServices() {        ...        mActivityManagerService.systemReady(new Runnable() {            @Override            public void run() {                Slog.i(TAG, "Making services ready");                mSystemServiceManager.startBootPhase(                        SystemService.PHASE_ACTIVITY_MANAGER_READY);                try {                    mActivityManagerService.startObservingNativeCrashes();                } catch (Throwable e) {                    reportWtf("observing native crashes", e);                }                Slog.i(TAG, "WebViewFactory preparation");                WebViewFactory.prepareWebViewInSystemServer();                try {                    startSystemUi(context);                } catch (Throwable e) {                    reportWtf("starting System UI", e);                }                try {                    if (mountServiceF != null) mountServiceF.systemReady();                } catch (Throwable e) {                    reportWtf("making Mount Service ready", e);                }                try {                    if (networkScoreF != null) networkScoreF.systemReady();                } catch (Throwable e) {                    reportWtf("making Network Score Service ready", e);                }                try {                    if (networkManagementF != null) networkManagementF.systemReady();                } catch (Throwable e) {                    reportWtf("making Network Managment Service ready", e);                }                try {                    if (networkStatsF != null) networkStatsF.systemReady();                } catch (Throwable e) {                    reportWtf("making Network Stats Service ready", e);                }                try {                    if (networkPolicyF != null) networkPolicyF.systemReady();                } catch (Throwable e) {                    reportWtf("making Network Policy Service ready", e);                }                try {                    if (connectivityF != null) connectivityF.systemReady();                } catch (Throwable e) {                    reportWtf("making Connectivity Service ready", e);                }                try {                    if (audioServiceF != null) audioServiceF.systemReady();                } catch (Throwable e) {                    reportWtf("Notifying AudioService running", e);                }                Watchdog.getInstance().start();                // It is now okay to let the various system services start their                // third party code...                mSystemServiceManager.startBootPhase(                        SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);                try {                    if (wallpaperF != null) wallpaperF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying WallpaperService running", e);                }                try {                    if (immF != null) immF.systemRunning(statusBarF);                } catch (Throwable e) {                    reportWtf("Notifying InputMethodService running", e);                }                try {                    if (locationF != null) locationF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying Location Service running", e);                }                try {                    if (countryDetectorF != null) countryDetectorF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying CountryDetectorService running", e);                }                try {                    if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying NetworkTimeService running", e);                }                try {                    if (commonTimeMgmtServiceF != null) {                        commonTimeMgmtServiceF.systemRunning();                    }                } catch (Throwable e) {                    reportWtf("Notifying CommonTimeManagementService running", e);                }                try {                    if (textServiceManagerServiceF != null)                        textServiceManagerServiceF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying TextServicesManagerService running", e);                }                try {                    if (atlasF != null) atlasF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying AssetAtlasService running", e);                }                try {                    // TODO(BT) Pass parameter to input manager                    if (inputManagerF != null) inputManagerF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying InputManagerService running", e);                }                try {                    if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying TelephonyRegistry running", e);                }                try {                    if (mediaRouterF != null) mediaRouterF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying MediaRouterService running", e);                }                try {                    if (mmsServiceF != null) mmsServiceF.systemRunning();                } catch (Throwable e) {                    reportWtf("Notifying MmsService running", e);                }            }        });    }

在AMS的systemReady阶段

public void systemReady(final Runnable goingCallback) {        synchronized(this) {            if (mSystemReady) {                // If we're done calling all the receivers, run the next "boot phase" passed in                // by the SystemServer                if (goingCallback != null) {                    goingCallback.run();                }                return;            }            ...            // Start up initial activity.            mBooting = true;            startHomeActivityLocked(mCurrentUserId);            ... }

在startHomeActivityLocked处理中又会涉及到ActivityStack、ActivityThread等启动一个APK进程。

当需要启动一个apk时,从流程分析上来看,会通过ActivityManagerService的startProcessLocked来孵化出一条新的进程:

    private final void startProcessLocked(ProcessRecord app, String hostingType,            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {            ...            if (entryPoint == null) entryPoint = "android.app.ActivityThread";            checkTime(startTime, "startProcess: asking zygote to start proc");            Process.ProcessStartResult startResult = Process.start(entryPoint,                    app.processName, uid, uid, gids, debugFlags, mountExternal,                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,                    app.info.dataDir, entryPointArgs);            checkTime(startTime, "startProcess: returned from zygote!");            ...

Process类是Android原生的类,而不是Java包中的Process。传入的参数名是android.app.ActivityThread,在后面孵化进程时会使用到:

    public static final ProcessStartResult start(final String processClass,                                  final String niceName,                                  int uid, int gid, int[] gids,                                  int debugFlags, int mountExternal,                                  int targetSdkVersion,                                  String seInfo,                                  String abi,                                  String instructionSet,                                  String appDataDir,                                  String[] zygoteArgs) {        try {            return startViaZygote(processClass, niceName, uid, gid, gids,                    debugFlags, mountExternal, targetSdkVersion, seInfo,                    abi, instructionSet, appDataDir, zygoteArgs);        } catch (ZygoteStartFailedEx ex) {            Log.e(LOG_TAG,                    "Starting VM process through Zygote failed");            throw new RuntimeException(                    "Starting VM process through Zygote failed", ex);        }    }    private static ProcessStartResult startViaZygote(final String processClass,                                  final String niceName,                                  final int uid, final int gid,                                  final int[] gids,                                  int debugFlags, int mountExternal,                                  int targetSdkVersion,                                  String seInfo,                                  String abi,                                  String instructionSet,                                  String appDataDir,                                  String[] extraArgs)                                  throws ZygoteStartFailedEx {          ...          return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);        }    }    private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {            try {                primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);            } catch (IOException ioe) {                throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);            }        }        if (primaryZygoteState.matches(abi)) {            return primaryZygoteState;        }        // The primary zygote didn't match. Try the secondary.        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {            try {                secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);            } catch (IOException ioe) {                throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);            }        }        if (secondaryZygoteState.matches(abi)) {            return secondaryZygoteState;        }        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);    }

在这里可以看到ZygoteState.connect(ZYGOTE_SOCKET),通过sockect去和zygote通信了。在zygote模块有一个一直循环的looper,用来处理其他模块发过来的sockect信息:

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {        ArrayList fds = new ArrayList();        ArrayList peers = new ArrayList();        FileDescriptor[] fdArray = new FileDescriptor[4];        fds.add(sServerSocket.getFileDescriptor());        peers.add(null);        int loopCount = GC_LOOP_COUNT;        while (true) {            int index;            if (loopCount <= 0) {                gc();                loopCount = GC_LOOP_COUNT;            } else {                loopCount--;            }            try {                fdArray = fds.toArray(fdArray);                index = selectReadable(fdArray);            } catch (IOException ex) {                throw new RuntimeException("Error in select()", ex);            }            if (index < 0) {                throw new RuntimeException("Error in select()");            } else if (index == 0) {                ZygoteConnection newPeer = acceptCommandPeer(abiList);                peers.add(newPeer);                fds.add(newPeer.getFileDescriptor());            } else {                boolean done;                done = peers.get(index).runOnce();                if (done) {                    peers.remove(index);                    fds.remove(index);                }            }        }    }

在ZygoteConnection的runOnce处理其他模块发给Zygote的socket消息:

   boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {        ...        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,                    parsedArgs.appDataDir);        ...        try {            if (pid == 0) {                // in child                IoUtils.closeQuietly(serverPipeFd);                serverPipeFd = null;                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);                // should never get here, the child is expected to either                // throw ZygoteInit.MethodAndArgsCaller or exec().                return true;            } else {                // in parent...pid of < 0 means failure                IoUtils.closeQuietly(childPipeFd);                childPipeFd = null;                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);            }        } finally {            IoUtils.closeQuietly(childPipeFd);            IoUtils.closeQuietly(serverPipeFd);        }   }
    public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,          String instructionSet, String appDataDir) {        long startTime = SystemClock.elapsedRealtime();        VM_HOOKS.preFork();        checkTime(startTime, "Zygote.preFork");        int pid = nativeForkAndSpecialize(                  uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,                  instructionSet, appDataDir);        checkTime(startTime, "Zygote.nativeForkAndSpecialize");        VM_HOOKS.postForkCommon();        checkTime(startTime, "Zygote.postForkCommon");        return pid;    }
    private void handleChildProc(Arguments parsedArgs,            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)            throws ZygoteInit.MethodAndArgsCaller {            ...            if (parsedArgs.invokeWith != null) {                WrapperInit.execStandalone(parsedArgs.invokeWith,                        parsedArgs.classpath, className, mainArgs);            } else {                ClassLoader cloader;                if (parsedArgs.classpath != null) {                    cloader = new PathClassLoader(parsedArgs.classpath,                            ClassLoader.getSystemClassLoader());                } else {                    cloader = ClassLoader.getSystemClassLoader();                }                try {                    ZygoteInit.invokeStaticMain(cloader, className, mainArgs);                } catch (RuntimeException ex) {                    logAndPrintError(newStderr, "Error starting.", ex);                }            }        }    }

分析到这个地方,大概应该清楚了在需要新启动一个进程时,实际上是通过sockect消息发送给zygote,让zygote去孵化出一个进程来。并且在ZygoteInit.invokeStaticMain(cloader, className, mainArgs)通过main函数开始执行这个孵化进程,例如启动一个应用时,实际上是ActivityThread的main函数开始执行。应用进程就是这样一个一个通过zygote分裂出来的。

更多相关文章

  1. C语言函数的递归(上)
  2. 【腾讯Bugly干货分享】Android进程保活招式大全
  3. 理解Android系统的进程间通信原理(二)----RPC机制
  4. 框架层理解Activity生命周期(APP启动过程)
  5. Android性能测试工具APT使用指南
  6. Android中app进程ABI确定过程
  7. Android函数响应式编程最新RxJava-操作符入门(2)
  8. android 解决getColor()方法过时
  9. 通信之进程间通信-AIDL

随机推荐

  1. Android(安卓)signed APK程序正式签名方
  2. 安卓不知道怎么学?看十年码农如何回答这个
  3. Android系列开发博客资源汇总
  4. MVC架构设计与三层模型 & MVP思想精髓与
  5. Android:(8)GridView与ImageView
  6. Android(安卓)Kotlin使用指南
  7. Android(安卓)Studio中获取sha1证书指纹
  8. Android系统与安全
  9. Unity3D for Android(安卓)纹理压缩支持
  10. Android调用堆栈跟踪