Android 应用程序进程启动过程源码分析

在Zygote进程启动过程的源代码分析一文中介绍到,Zygote是java世界的开创者,所有的java应用进程都是通过Zygote孵化出来的。我们知道在Android应用程序框架层中,ActivityManagerService组件负责管理Android应用程序的创建,ActivityManagerService也是运行在独立的进程SystemServer中,SystemServer进程启动过程源码分析中介绍了SystemServer进程是如果通过开启线程来启动各种服务,ActivityManagerService也是System
 Server启动的服务之一。

ActivityManagerService请求创建应用程序进程

当系统决定要在一个新的进程中启动一个Activity或者Service时,它就会创建一个新的进程,ActivityManagerService通过调用startProcessLocked函数来为应用程序启动新的进程。
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
 


final ProcessRecord startProcessLocked(String processName,

        ApplicationInfo info, boolean knownToBeDead, int intentFlags,

        String hostingType, ComponentName hostingName, boolean allowWhileBooting,

        boolean isolated) {

    ProcessRecord app;

    //是否在现有进程中启动

    if (!isolated) {

        //从现有进程表mProcessNames中查找相应的进程描述符ProcessRecord

        app = getProcessRecordLocked(processName, info.uid);

    } else {

        // If this is an isolated process, it can't re-use an existing process.

        app = null;

    }

    // We don't have to do anything more if:

    // (1) There is an existing application record; and

    // (2) The caller doesn't think it is dead, OR there is no thread

    //     object attached to it so we know it couldn't have crashed; and

    // (3) There is a pid assigned to it, so it is either starting or

    //     already running.

    if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName

            + " app=" + app + " knownToBeDead=" + knownToBeDead

            + " thread=" + (app != null ? app.thread : null)

            + " pid=" + (app != null ? app.pid : -1));

    if (app != null && app.pid > 0) {

        if (!knownToBeDead || app.thread == null) {

            // We already have the app running, or are waiting for it to

            // come up (we have a pid but not yet its thread), so keep it.

            if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);

            // If this is a new package in the process, add the package to the list

            app.addPackage(info.packageName);

            return app;

        } else {

            // An application record is attached to a previous process,

            // clean it up now.

            if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);

            handleAppDiedLocked(app, true, true);

        }

    }

    String hostingNameStr = hostingName != null

            ? hostingName.flattenToShortString() : null;

    if (!isolated) {

        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {

            // If we are in the background, then check to see if this process

            // is bad.  If so, we will just silently fail.

            if (mBadProcesses.get(info.processName, info.uid) != null) {

                if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid

                        + "/" + info.processName);

                return null;

            }

        } else {

            // When the user is explicitly starting a process, then clear its

            // crash count so that we won't make it bad until they see at

            // least one crash dialog again, and make the process good again

            // if it had been bad.

            if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid

                    + "/" + info.processName);

            mProcessCrashTimes.remove(info.processName, info.uid);

            if (mBadProcesses.get(info.processName, info.uid) != null) {

                EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,info.processName);

                mBadProcesses.remove(info.processName, info.uid);

                if (app != null) {

                    app.bad = false;

                }

            }

        }

    }

 

    if (app == null) {

        //在ActivityManagerService中为新进程创建一个ProcessRecord实例

        app = newProcessRecordLocked(null, info, processName, isolated);

        if (app == null) {

            Slog.w(TAG, "Failed making new process record for "

                    + processName + "/" + info.uid + " isolated=" + isolated);

            return null;

        }

        //添加到进程列表中

        mProcessNames.put(processName, app.uid, app);

        //如果当前服务运行在独立进程中,添加到独立进程表mIsolatedProcesses中

        /**

         * SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();

         * The currently running isolated processes.

         */

        if (isolated) {

            mIsolatedProcesses.put(app.uid, app);

        }

    } else {

        // If this is a new package in the process, add the package to the list

        app.addPackage(info.packageName);

    }

    // If the system is not ready yet, then hold off on starting this

    // process until it is.

    if (!mProcessesReady && !isAllowedWhileBooting(info) && !allowWhileBooting) {

        /**

         * final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();

         * List of records for processes that someone had tried to start before the

         * system was ready.  We don't start them at that point, but ensure they

         * are started by the time booting is complete.

         */

        if (!mProcessesOnHold.contains(app)) {

            mProcessesOnHold.add(app);

        }

        if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);

        return app;

    }

    //调用startProcessLocked启动新的应用程序进程

    startProcessLocked(app, hostingType, hostingNameStr);

    return (app.pid != 0) ? app : null;

}


private final void startProcessLocked(ProcessRecord app,

        String hostingType, String hostingNameStr) {

    if (app.pid > 0 && app.pid != MY_PID) {

        synchronized (mPidsSelfLocked) {

            mPidsSelfLocked.remove(app.pid);

            mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

        }

        app.pid = 0;

    }

    //系统准备好了,马上启动服务,因此如果mProcessesOnHold列表中包含当前启动的服务,则需移除

    if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,

            "startProcessLocked removing on hold: " + app);

    mProcessesOnHold.remove(app);

    //唤醒进程信息收集线程

    updateCpuStats();

    System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);

    mProcDeaths[0] = 0;

    try {

        int uid = app.uid;

        int[] gids = null;

        if (!app.isolated) {

            try {

                gids = mContext.getPackageManager().getPackageGids(

                        app.info.packageName);

            } catch (PackageManager.NameNotFoundException e) {

                Slog.w(TAG, "Unable to retrieve gids", e);

            }

        }

        if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {

            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL

                    && mTopComponent != null

                    && app.processName.equals(mTopComponent.getPackageName())) {

                uid = 0;

            }

            if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL

                    && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {

                uid = 0;

            }

        }

        //设置应用程序进程创建方式

        int debugFlags = 0;

        if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {

            debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;

            // Also turn on CheckJNI for debuggable apps. It's quite

            // awkward to turn on otherwise.

            debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;

        }

        // Run the app in safe mode if its manifest requests so or the

        // system is booted in safe mode.

        if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||

            Zygote.systemInSafeMode == true) {

            debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;

        }

        if ("1".equals(SystemProperties.get("debug.checkjni"))) {

            debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;

        }

        if ("1".equals(SystemProperties.get("debug.jni.logging"))) {

            debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;

        }

        if ("1".equals(SystemProperties.get("debug.assert"))) {

            debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;

        }

        //它调用了Process.start函数开始为应用程序创建新的进程,

        //它传入一个第一个参数为"android.app.ActivityThread",这就是进程初始化时要加载的Java类了,

        //把这个类加载到进程之后,就会把它里面的静态成员函数main作为进程的入口点,

        Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",

                app.processName, uid, uid, gids, debugFlags,

                app.info.targetSdkVersion, null);

        BatteryStatsImpl bs = app.batteryStats.getBatteryStats();

        synchronized (bs) {

            if (bs.isOnBattery()) {

                app.batteryStats.incStartsLocked();

            }

        }

        EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,

                app.processName, hostingType,

                hostingNameStr != null ? hostingNameStr : "");

        //如果启动的进程是一个持久进程,则添加到Watchdog中监控

        if (app.persistent) {

            Watchdog.getInstance().processStarted(app.processName, startResult.pid);

        }

        StringBuilder buf = mStringBuilder;

        buf.setLength(0);

        buf.append("Start proc ");

        buf.append(app.processName);

        buf.append(" for ");

        buf.append(hostingType);

        if (hostingNameStr != null) {

            buf.append(" ");

            buf.append(hostingNameStr);

        }

        buf.append(": pid=");

        buf.append(startResult.pid);

        buf.append(" uid=");

        buf.append(uid);

        buf.append(" gids={");

        if (gids != null) {

            for (int gi=0; gi<gids.length; gi++) {

                if (gi != 0) buf.append(", ");

                buf.append(gids[gi]);

 

            }

        }

        buf.append("}");

        Slog.i(TAG, buf.toString());

        app.pid = startResult.pid;

        app.usingWrapper = startResult.usingWrapper;

        app.removed = false;

        //将新创建的进程描述符ProcessRecord保存到mPidsSelfLocked链表中

        /**

        * final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();

        * All of the processes we currently have running organized by pid.

        * The keys are the pid running the application.

        */

        synchronized (mPidsSelfLocked) {

            this.mPidsSelfLocked.put(startResult.pid, app);

            Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);

            msg.obj = app;

            mHandler.sendMessageDelayed(msg, startResult.usingWrapper

                    ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);

        }

    } catch (RuntimeException e) {

        // XXX do better error recovery.

        app.pid = 0;

        Slog.e(TAG, "Failure starting process " + app.processName, e);

    }

    if (LC_RAM_SUPPORT

            && ((app.info.flags & (ApplicationInfo.FLAG_SYSTEM)) == (ApplicationInfo.FLAG_SYSTEM))

            && (CONTACTS_PROCESS_NAME.equals(app.processName))) {

        app.isContactsProcess = true;

    }

    if (LC_RAM_SUPPORT && fixAdjList.containsKey(app.processName)) {

        app.fixAdj = fixAdjList.get(app.processName);

        Slog.v(TAG, "app[" + app.processName + "] has fix adj:" + app.fixAdj);

    }

}
在该函数里,首先获取即将创建的应用程序的gid和uid,并设置应用程序进程创建方式,然后调用Process类的start()函数来创建一个新的应用程序进程,同时指定新进程执行的入口为ActivityThread类的main函数。
frameworks\base\core\java\android\os\Process.java
 


public static final ProcessStartResult start(final String processClass,

                              final String niceName,

                              int uid, int gid, int[] gids,

                              int debugFlags, int targetSdkVersion,

                              String[] zygoteArgs) {

    try {

        return startViaZygote(processClass, niceName, uid, gid, gids,

                debugFlags, targetSdkVersion, zygoteArgs);

    } catch (ZygoteStartFailedEx ex) {

        Log.e(LOG_TAG,"Starting VM process through Zygote failed");

        throw new RuntimeException("Starting VM process through Zygote failed", ex);

    }

}
该函数直接调用startViaZygote()函数来创建一个新的应用程序进程。


private static ProcessStartResult startViaZygote(final String processClass,

                              final String niceName,

                              final int uid, final int gid,

                              final int[] gids,

                              int debugFlags, int targetSdkVersion,

                              String[] extraArgs)

                              throws ZygoteStartFailedEx {

    synchronized(Process.class) {

        ArrayList<String> argsForZygote = new ArrayList<String>();

        // --runtime-init, --setuid=, --setgid=,

        // and --setgroups= must go first

        argsForZygote.add("--runtime-init");

        argsForZygote.add("--setuid=" + uid);

        argsForZygote.add("--setgid=" + gid);

        if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {

            argsForZygote.add("--enable-jni-logging");

        }

        if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {

            argsForZygote.add("--enable-safemode");

        }

        if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {

            argsForZygote.add("--enable-debugger");

        }

        if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {

            argsForZygote.add("--enable-checkjni");

        }

        if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {

            argsForZygote.add("--enable-assert");

        }

        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

        //TODO optionally enable debuger

        //argsForZygote.add("--enable-debugger");

        // --setgroups is a comma-separated list

        if (gids != null && gids.length > 0) {

            StringBuilder sb = new StringBuilder();

            sb.append("--setgroups=");

            int sz = gids.length;

            for (int i = 0; i < sz; i++) {

                if (i != 0) {

                    sb.append(',');

                }

                sb.append(gids[i]);

            }

            argsForZygote.add(sb.toString());

        }

        if (niceName != null) {

            argsForZygote.add("--nice-name=" + niceName);

        }

        argsForZygote.add(processClass);

        if (extraArgs != null) {

            for (String arg : extraArgs) {

                argsForZygote.add(arg);

            }

        }

        //将通过Socket方式将参数列表发送给Zygote进程

        return zygoteSendArgsAndGetResult(argsForZygote);

    }

}
 

在该函数里,首先将新的应用程序进程启动参数保存到argsForZygote列表中,然后调用zygoteSendArgsAndGetPid将应用程序进程启动参数发送到Zygote进程。
frameworks\base\core\java\android\os\Process.java
 


private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)

        throws ZygoteStartFailedEx {

    //创建一个客户端Socket,并连接到Zygote进程的Socket服务端

    openZygoteSocketIfNeeded();

    try {

        /**

         * See com.android.internal.os.ZygoteInit.readArgumentList()

         * Presently the wire format to the zygote process is:

         * a) a count of arguments (argc, in essence)

         * b) a number of newline-separated argument strings equal to count

         *

         * After the zygote process reads these it will write the pid of

         * the child or -1 on failure, followed by boolean to

         * indicate whether a wrapper process was used.

         */

        //将应用程序启动参数列表写入到Socket

        sZygoteWriter.write(Integer.toString(args.size()));

        sZygoteWriter.newLine();

        int sz = args.size();

        for (int i = 0; i < sz; i++) {

            String arg = args.get(i);

            if (arg.indexOf('\n') >= 0) {

                throw new ZygoteStartFailedEx(

                        "embedded newlines not allowed");

            }

            sZygoteWriter.write(arg);

            sZygoteWriter.newLine();

        }

        sZygoteWriter.flush();

        //读取Zygote进程返回来的结果

        ProcessStartResult result = new ProcessStartResult();

        result.pid = sZygoteInputStream.readInt();

        if (result.pid < 0) {

            throw new ZygoteStartFailedEx("fork() failed");

        }

        result.usingWrapper = sZygoteInputStream.readBoolean();

        return result;

    } catch (IOException ex) {

        try {

            if (sZygoteSocket != null) {

                sZygoteSocket.close();

            }

        } catch (IOException ex2) {

            // we're going to fail anyway

            Log.e(LOG_TAG,"I/O exception on routine close", ex2);

        }

        sZygoteSocket = null;

        throw new ZygoteStartFailedEx(ex);

    }

}
 

该函数首先在SystemServer进程中创建一个客户端LocalSocket,并连接到Zygote进程的名为"zygote"的服务端Socket


private static void openZygoteSocketIfNeeded() 

        throws ZygoteStartFailedEx {

    int retryCount;

    if (sPreviousZygoteOpenFailed) {

        /*

         * If we've failed before, expect that we'll fail again and

         * don't pause for retries.

         */

        retryCount = 0;

    } else {

        retryCount = 10;            

    }

 

    /*

     * See bug #811181: Sometimes runtime can make it up before zygote.

     * Really, we'd like to do something better to avoid this condition,

     * but for now just wait a bit...

     */

    for (int retry = 0; (sZygoteSocket == null) && (retry < (retryCount + 1)); retry++ ) {

        if (retry > 0) {

            try {

                Log.i("Zygote", "Zygote not up yet, sleeping...");

                Thread.sleep(ZYGOTE_RETRY_MILLIS);

            } catch (InterruptedException ex) {

                // should never happen

            }

        }

        try {

            sZygoteSocket = new LocalSocket();

            //连接到Zygote进程的服务端zygote Socket

            sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, LocalSocketAddress.Namespace.RESERVED));

            sZygoteInputStream = new DataInputStream(sZygoteSocket.getInputStream());

            sZygoteWriter = new BufferedWriter(new OutputStreamWriter(

                                sZygoteSocket.getOutputStream()),256);

            Log.i("Zygote", "Process: zygote socket opened");

            sPreviousZygoteOpenFailed = false;

            break;

        } catch (IOException ex) {

            //Socket操作失败,关闭该Socket

            if (sZygoteSocket != null) {

                try {

                    sZygoteSocket.close();

                } catch (IOException ex2) {

                    Log.e(LOG_TAG,"I/O exception on close after exception",ex2);

                }

            }

            sZygoteSocket = null;

        }

    }

 

    if (sZygoteSocket == null) {

        sPreviousZygoteOpenFailed = true;

        throw new ZygoteStartFailedEx("connect failed");                 

    }

}
 

最后将参数列表写入到创建的客户端Socket中,从而将应用程序启动参数发送给Zygote进程,启动参数包括:

"--runtime-init""--setuid=x""--setgid=x""--enable-safemode""--enable-debugger""--enable-checkjni""--enable-assert""--setgroups=x""--nice-name=x""android.app.ActivityThread"
要启动一个新的应用程序进程,应用程序不能直接请求Zygote来fork出新进程,而是要通过SystemServer进程中的ActivityManagerService服务来请求Zygote进程。
 

Zygote进程孵化应用程序进程

ActivityManagerService通过Socket方式将请求参数发送给Zygote,此时Zygote正在runSelectLoopMode()函数中监听Socket连接。

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
 


private static void runSelectLoopMode() throws MethodAndArgsCaller {

    ArrayList<FileDescriptor> fds = new ArrayList();

    ArrayList<ZygoteConnection> peers = new ArrayList();

    FileDescriptor[] fdArray = new FileDescriptor[4];

    

    fds.add(sServerSocket.getFileDescriptor());

    peers.add(null);

 

    int loopCount = GC_LOOP_COUNT;

    while (true) {

        int index;

        /*

         * Call gc() before we block in select().

         * It's work that has to be done anyway, and it's better

         * to avoid making every child do it.  It will also

         * madvise() any free memory as a side-effect.

         *

         * Don't call it every time, because walking the entire

         * heap is a lot of overhead to free a few hundred bytes.

         */

        if (loopCount <= 0) {

            gc();

            loopCount = GC_LOOP_COUNT;

        } else {

            loopCount--;

        }

        try {

            fdArray = fds.toArray(fdArray);

            //监听zygote Socket是否有客户端连接

            index = selectReadable(fdArray);

        } catch (IOException ex) {

            throw new RuntimeException("Error in select()", ex);

        }

        if (index < 0) {

            throw new RuntimeException("Error in select()");

        //zygote socket句柄中有事件到来,表示有客户端的socket连接

        } else if (index == 0) {

            //接收客户端连接请求,并将客户端请求添加到句柄池中监控

            ZygoteConnection newPeer = acceptCommandPeer();

            peers.add(newPeer);

            fds.add(newPeer.getFileDesciptor());

        //客户端连接Socket有事件到来,表示SystemServer进程正在发送应用程序启动参数

        } else {

            boolean done;

            //孵化一个新的应用程序进程

            done = peers.get(index).runOnce();

            //从socket句柄池中移除客户连接socket句柄

            if (done) {

                peers.remove(index);

                fds.remove(index);

            }

        }

    }

}
 

当接收到新的客户端socket连接请求时,函数从selectReadable中返回,并为该客户端连接创建一个ZygoteConnection实例;当Zygote接收到SystemServer进程发送过来的应用程序进程启动参数时,就会调用相应ZygoteConnection实例的runOnce()函数来启动一个新的进程。

frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java
 


boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

 

    String args[];

    Arguments parsedArgs = null;

    FileDescriptor[] descriptors;

    try {

        //读取参数

        args = readArgumentList();

        descriptors = mSocket.getAncillaryFileDescriptors();

    } catch (IOException ex) {

        Log.w(TAG, "IOException on command socket " + ex.getMessage());

        closeSocket();

        return true;

    }

    if (args == null) {

        // EOF reached.

        closeSocket();

        return true;

    }

    /** the stderr of the most recent request, if avail */

    PrintStream newStderr = null;

 

    if (descriptors != null && descriptors.length >= 3) {

        newStderr = new PrintStream(new FileOutputStream(descriptors[2]));

    }

    int pid = -1;

    FileDescriptor childPipeFd = null;

    FileDescriptor serverPipeFd = null;

    try {

        parsedArgs = new Arguments(args);

        applyUidSecurityPolicy(parsedArgs, peer);

        applyRlimitSecurityPolicy(parsedArgs, peer);

        applyCapabilitiesSecurityPolicy(parsedArgs, peer);

        applyInvokeWithSecurityPolicy(parsedArgs, peer);

        applyDebuggerSystemProperty(parsedArgs);

        applyInvokeWithSystemProperty(parsedArgs);

        int[][] rlimits = null;

 

        if (parsedArgs.rlimits != null) {

            rlimits = parsedArgs.rlimits.toArray(intArray2d);

        }

 

        if (parsedArgs.runtimeInit && parsedArgs.invokeWith != null) {

            FileDescriptor[] pipeFds = Libcore.os.pipe();

            childPipeFd = pipeFds[1];

            serverPipeFd = pipeFds[0];

            ZygoteInit.setCloseOnExec(serverPipeFd, true);

        }

        //创建子进程,而且有两个返回值,一个是在当前进程中返回的,一个是在新创建的进程中返回,

        //即在当前进程的子进程中返回,在当前进程中的返回值就是新创建的子进程的pid值,而在子进程中的返回值是0。

        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,

                parsedArgs.gids, parsedArgs.debugFlags, rlimits);

    } catch (IOException ex) {

        logAndPrintError(newStderr, "Exception creating pipe", ex);

    } catch (ErrnoException ex) {

        logAndPrintError(newStderr, "Exception creating pipe", ex);

    } catch (IllegalArgumentException ex) {

        logAndPrintError(newStderr, "Invalid zygote arguments", ex);

    } catch (ZygoteSecurityException ex) {

        logAndPrintError(newStderr,

                "Zygote security policy prevents request: ", ex);

    }

    try {

        //父子进程运行分界线

        if (pid == 0) {

            //子进程执行过程

            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 {

            //父进程,也就是Zygote进程执行过程

            IoUtils.closeQuietly(childPipeFd);

            childPipeFd = null;

            return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);

        }

    } finally {

        IoUtils.closeQuietly(childPipeFd);

        IoUtils.closeQuietly(serverPipeFd);

    }

}
 

函数首先调用readArgumentList读取ActivityManagerService发送过来的应用程序启动参数,接着根据参数调用forkAndSpecialize函数fork一个新的应用程序进程,就是复制一份Zygote进程地址空间,当返回的pid=0时,表示当前是新创建的应用程序进程,否则为Zygote进程的函数执行返回。首先来分析Zygote进程返回后执行的工作:

frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java
 


private boolean handleParentProc(int pid,

        FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {

    if (pid > 0) {

        setChildPgid(pid);

    }

    if (descriptors != null) {

        for (FileDescriptor fd: descriptors) {

            IoUtils.closeQuietly(fd);

        }

    }

    boolean usingWrapper = false;

    if (pipeFd != null && pid > 0) {

        DataInputStream is = new DataInputStream(new FileInputStream(pipeFd));

        int innerPid = -1;

        try {

            innerPid = is.readInt();

        } catch (IOException ex) {

            Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex);

        } finally {

            try {

                is.close();

            } catch (IOException ex) {

            }

        }

        // Ensure that the pid reported by the wrapped process is either the

        // child process that we forked, or a descendant of it.

        if (innerPid > 0) {

            int parentPid = innerPid;

            while (parentPid > 0 && parentPid != pid) {

                parentPid = Process.getParentPid(parentPid);

            }

            if (parentPid > 0) {

                Log.i(TAG, "Wrapped process has pid " + innerPid);

                pid = innerPid;

                usingWrapper = true;

            } else {

                Log.w(TAG, "Wrapped process reported a pid that is not a child of "

                        + "the process that we forked: childPid=" + pid

                        + " innerPid=" + innerPid);

            }

        }

    }

    //将创建的应用程序进程ID返回给SystemServer进程的ActivityManagerService服务

    try {

        mSocketOutStream.writeInt(pid);

        mSocketOutStream.writeBoolean(usingWrapper);

    } catch (IOException ex) {

        Log.e(TAG, "Error reading from command socket", ex);

        return true;

    }

    /*

     * If the peer wants to use the socket to wait on the

     * newly spawned process, then we're all done.

     */

    if (parsedArgs.peerWait) {

        try {

            mSocket.close();

        } catch (IOException ex) {

            Log.e(TAG, "Zygote: error closing sockets", ex);

        }

        return true;

    }

    return false;

}
 

Zygote进程将新创建的应用程序进程写回到SystemServer进程后,从函数handleParentProc一路返回到runSelectLoopMode(),继续监听客户端进程的Socket连接请求。

Zygote孵化出新的应用程序进程后,新的应用程序进程将执行handleChildProc函数,从此与其父进程Zygote分道扬镳。

frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java


private void handleChildProc(Arguments parsedArgs,

        FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)

        throws ZygoteInit.MethodAndArgsCaller {

    /*

     * Close the socket, unless we're in "peer wait" mode, in which

     * case it's used to track the liveness of this process.

     */

 

    if (parsedArgs.peerWait) {

        try {

            ZygoteInit.setCloseOnExec(mSocket.getFileDescriptor(), true);

            sPeerWaitSocket = mSocket;

        } catch (IOException ex) {

            Log.e(TAG, "Zygote Child: error setting peer wait "

                    + "socket to be close-on-exec", ex);

        }

    } else {//关闭从Zygote进程复制过来的Socket连接

        closeSocket();

        ZygoteInit.closeServerSocket();

    }

    if (descriptors != null) {

        try {

            //为新创建的应用程序进程重新打开标准输入输出控制台

            ZygoteInit.reopenStdio(descriptors[0],descriptors[1], descriptors[2]);

            for (FileDescriptor fd: descriptors) {

                IoUtils.closeQuietly(fd);

            }

            newStderr = System.err;

        } catch (IOException ex) {

            Log.e(TAG, "Error reopening stdio", ex);

        }

    }

    //设置新进程名称

    if (parsedArgs.niceName != null) {

        Process.setArgV0(parsedArgs.niceName);

    }

    //重新初始化Runtime

    if (parsedArgs.runtimeInit) {

        if (parsedArgs.invokeWith != null) {

            WrapperInit.execApplication(parsedArgs.invokeWith,

                    parsedArgs.niceName, parsedArgs.targetSdkVersion,

                    pipeFd, parsedArgs.remainingArgs);

        } else {

            //为应用程序进程启动Binder线程池

            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs);

        }

    } else {

        String className;

        try {

            //读取新进程执行的类名,在Process.start()函数中,传过来的类名为:"android.app.ActivityThread"

            className = parsedArgs.remainingArgs[0];

        } catch (ArrayIndexOutOfBoundsException ex) {

            logAndPrintError(newStderr,"Missing required class name argument", null);

            return;

        }

        String[] mainArgs = new String[parsedArgs.remainingArgs.length - 1];

        System.arraycopy(parsedArgs.remainingArgs, 1,mainArgs, 0, mainArgs.length);

        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();

            }

            //加载并执行"android.app.ActivityThread"类

            try {

                ZygoteInit.invokeStaticMain(cloader, className, mainArgs);

            } catch (RuntimeException ex) {

                logAndPrintError(newStderr, "Error starting.", ex);

            }

        }

    }

}

由于应用程序启动参数中已经设置了"--runtime-init"标志位,因此新创建的应用程序进程将调用RuntimeInit.zygoteInit()函数来初始化运行时库,为应用程序启动Binder线程池,完成这些准备工作后,调用应用程序进程的入口函数ActivityThread.main()为应用程序进程创建消息循环。

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


public static final void zygoteInit(int targetSdkVersion, String[] argv)

        throws ZygoteInit.MethodAndArgsCaller {

    if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

    //重定向Log输出流

    redirectLogStreams();

    //初始化运行环境

    commonInit();

    //启动Binder线程池

    nativeZygoteInit();

    //调用程序入口函数

    applicationInit(targetSdkVersion, argv);

}
 

1. 初始化Log输出流


/**

 * 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.初始化运行环境


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

     */

    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.

     */

    LogManager.getLogManager().reset();

    new AndroidConfig();

 

    /*

     * Sets the default HTTP User-Agent used by HttpURLConnection.

     */

    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.

     */

    String trace = SystemProperties.get("ro.kernel.android.tracing");

    if (trace.equals("1")) {

        Slog.i(TAG, "NOTE: emulator trace profiling enabled");

        Debug.enableEmulatorTraceOutput();

    }

 

    initialized = true;

}
 

3.启动Binder线程池

 

关于Binder线程池的启动过程请参考Android应用程序启动Binder线程源码分析

4.调用进程入口函数


static void invokeStaticMain(ClassLoader loader,

        String className, String[] argv)

        throws ZygoteInit.MethodAndArgsCaller {

    //加载"android.app.ActivityThread"类

    Class<?> cl;

    try {

        cl = loader.loadClass(className);

    } catch (ClassNotFoundException ex) {

        throw new RuntimeException("Missing class when invoking static main " + className,

                ex);

    }

    //通过类反射机制查找ActivityThread类中的main函数

    Method m;

    try {

        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);

    }

    //获取main函数的修饰符

    int modifiers = m.getModifiers();

    //进程入口函数必须为静态Public类型

    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {

        throw new RuntimeException("Main method is not public and static on " + className);

    }

    /*

     * This throw gets caught in ZygoteInit.main(), which responds

     * by invoking the exception's run() method. This arrangement

     * clears up all the stack frames that were required in setting

     * up the process.

     */

    throw new ZygoteInit.MethodAndArgsCaller(m, argv);

}
抛出MethodAndArgsCaller异常,并在ZygoteInit.main()函数中捕获该异常,这样就可以清除应用程序进程创建过程的调用栈,将应用程序启动的入口函数设置为ActivityThread.main()
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
 


public static void main(String argv[]) {

    try {

        ...

    //捕获MethodAndArgsCaller异常

    } catch (MethodAndArgsCaller caller) {

        caller.run();

    } catch (RuntimeException ex) {

        Log.e(TAG, "Zygote died with exception", ex);

        closeServerSocket();

        throw ex;

    }

}
 

在该函数里,捕获了MethodAndArgsCaller异常,并调用MethodAndArgsCaller类的run()方法来处理异常:


public static class MethodAndArgsCaller extends Exception implements Runnable {

    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);

        }

    }

}
 

这里通过反射机制调用ActivityThread类的main函数,到此新的应用程序进程就创建完毕,同时新的应用程序从ActivityThread.main()函数中开始运行。

frameworks\base\core\java\android\app\ActivityThread.java
 


public static void main(String[] args) {

    SamplingProfilerIntegration.start();

    // CloseGuard defaults to true and can be quite spammy.  We

    // disable it here, but selectively enable it later (via

    // StrictMode) on debug builds, but using DropBox, not logs.

    CloseGuard.setEnabled(false);

    Process.setArgV0("<pre-initialized>");

    //为新的应用程序创建消息队列

    Looper.prepareMainLooper();

    if (sMainThreadHandler == null) {

        sMainThreadHandler = new Handler();

    }

    //创建一个ActivityThread对象,初始化应用程序运行环境,每一个进程对应一个ActivityThread实例

    ActivityThread thread = new ActivityThread();

    //建立与ActivityManagerService之间的Binder通信通道

    thread.attach(false);

    AsyncTask.init();

    

    if (false) {

        Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));

    }

    //为新的应用程序进程启动消息循环,这个消息循环就是应用程序主线程消息循环

    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");

}
 

至此,Android应用程序进程启动过程的源代码就分析完成了,以下是android应用进程的启动过程的时序图:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值