Android Appアプリケーション起動プロセス(二)

72530 ワード

前回の終わりの場所に戻ります.
void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    r.getStack().setLaunchTime(r);

    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                        mService.mProcessStats);
            }
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
    }

    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

プロセスが存在する場合appを起動
realStartActivity Lockedメソッドを参照
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {

    ...
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
        System.identityHashCode(r), r.info,
        // TODO: Have this take the merged configuration instead of separate global and
        // override configs.
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
        r.persistentState, results, newIntents, !andResume,
        mService.isNextTransitionForward(), profilerInfo);
    ...

    return true;
}

ここでappが呼び出されましたthread.scheduleLaunchActivity、ここで実際に呼び出されたのはActivity ThreadのサブクラスApplicationThreadのscheduleLaunchActivityメソッドです
// we use token to identify this activity without having to send the
// activity itself back to the activity manager. (matters more with ipc)
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
        ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
        CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
        int procState, Bundle state, PersistableBundle persistentState,
        List pendingResults, List pendingNewIntents,
        boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

    updateProcessState(procState, false);

    ActivityClientRecord r = new ActivityClientRecord();

    r.token = token;
    r.ident = ident;
    r.intent = intent;
    r.referrer = referrer;
    r.voiceInteractor = voiceInteractor;
    r.activityInfo = info;
    r.compatInfo = compatInfo;
    r.state = state;
    r.persistentState = persistentState;

    r.pendingResults = pendingResults;
    r.pendingIntents = pendingNewIntents;

    r.startsNotResumed = notResumed;
    r.isForward = isForward;

    r.profilerInfo = profilerInfo;

    r.overrideConfig = overrideConfig;
    updatePendingConfiguration(curConfig);

    sendMessage(H.LAUNCH_ACTIVITY, r);
}
//          Handler     Activity
//--->
private void sendMessage(int what, Object obj) {
    sendMessage(what, obj, 0, 0, false);
}

//--->
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    if (DEBUG_MESSAGES) Slog.v(
        TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
        + ": " + arg1 + " / " + obj);
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

...
public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) {
        case LAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
...
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...

    // Initialize before creating the activity
    WindowManagerGlobal.initialize();
    //    Activity
    Activity a = performLaunchActivity(r, customIntent);

    ...
}

この方法では、Activityに関する重要な方法を見ることができます.例えば、activity.attachは現在のActivity Threadにバインドされています.setThemeのテーマ設定など、ここまでは基本的にActivityの範疇に入っていますが、次は別の状況、新規プロセスの状況を見てみましょう.
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

    ...
    Activity activity = null;

    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
        if (localLOGV) Slog.v(
                TAG, r + ": app=" + app
                + ", appName=" + app.getPackageName()
                + ", pkg=" + r.packageInfo.getPackageName()
                + ", comp=" + r.intent.getComponent().toShortString()
                + ", dir=" + r.packageInfo.getAppDir());

        if (activity != null) {
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (r.overrideConfig != null) {
                config.updateFrom(r.overrideConfig);
            }
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }
            appContext.setOuterContext(activity);
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            checkAndBlockForNetworkAccess();
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            if (!activity.mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString() +
                    " did not call through to super.onCreate()");
            }
            r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
            if (!r.activity.mFinished) {
                if (r.isPersistable()) {
                    if (r.state != null || r.persistentState != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                r.persistentState);
                    }
                } else if (r.state != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }
            if (!r.activity.mFinished) {
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state,
                            r.persistentState);
                } else {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onPostCreate()");
                }
            }
        }
        r.paused = true;

        mActivities.put(r.token, r);

    } catch (SuperNotCalledException e) {
        throw e;

    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to start activity " + component
                + ": " + e.toString(), e);
        }
    }

    return activity;
}

新規プロセス起動app
0xa
サービスを見てstartProcessLocked(r.processName, r.info.applicationInfo, true, 0, “activity”, r.intent.getComponent(), false, false, true); ここでまたActivityManagerServiceというクラスに戻ります.ここで注意しなければならないことがあります.startProcessLockedメソッドにはstartProcessLockedメソッドが呼び出されています.パラメータが異なり、注意すべきパラメータをentryPointと呼び、パラメータがnullです.
final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    long startTime = SystemClock.elapsedRealtime();
    ProcessRecord app;
    ...

    checkTime(startTime, "startProcess: stepping in to startProcess");
    startProcessLocked(
            app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
    checkTime(startTime, "startProcess: done starting proc!");
    return (app.pid != 0) ? app : null;
}

0xb
void startProcessLocked(ProcessRecord app,String hostingType,String hostingNameStr,String abioverride,String entryPoint,String[]entryPointArgs)も呼び出されました
//startProcessLocked  

...
//     0xa      entryPoint,      "android.app.ActivityThread"
 //       ,       main  
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
...
startResult = Process.start(entryPoint,
    app.processName, uid, uid, gids, debugFlags, mountExternal,
    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
    app.info.dataDir, invokeWith, entryPointArgs);
...

Process.java
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 invokeWith,
                              String[] zygoteArgs) {
    return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}

各appプロセスはZygoteプロセスfork自身によって得られ、SystemServerプロセスも含めてZygote forkから出てきた.以下、zygoteProcessのコードを見てみると、ネット上でアプリケーション起動プロセスを分析した結果、appエントリはActivvtyThreadのmainメソッドであると結論した.では、このmainメソッドはどこで呼び出されますか.ここからどのくらい離れていますか.
ZygoteProcess.java
public final Process.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 invokeWith,
                                              String[] zygoteArgs) {
    try {
        return startViaZygote(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
        Log.e(LOG_TAG,
                "Starting VM process through Zygote failed");
        throw new RuntimeException(
                "Starting VM process through Zygote failed", ex);
    }
}

/**
 * Starts a new process via the zygote mechanism.
 *    zygote        
 */
private Process.ProcessStartResult startViaZygote(final String processClass,.....)throws ZygoteStartFailedEx {
    ...

    synchronized(mLock) {
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
}

/**
 *          zygote  ,zygote        pid
 * @throws ZygoteStartFailedEx if process start failed for any reason
 */
@GuardedBy("mLock")
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList args)
        throws ZygoteStartFailedEx {
    try {
        ...
        final BufferedWriter writer = zygoteState.writer;
        final DataInputStream inputStream = zygoteState.inputStream;

        writer.write(Integer.toString(args.size()));
        writer.newLine();

        for (int i = 0; i < sz; i++) {
            String arg = args.get(i);
            writer.write(arg);
            writer.newLine();
        }
        writer.flush();
        //         ,          pid         ,    
        Process.ProcessStartResult result = new Process.ProcessStartResult();

        // Always read the entire result from the input stream to avoid leaving
        // bytes in the stream for future process starts to accidentally stumble
        // upon.
        result.pid = inputStream.readInt();
        result.usingWrapper = inputStream.readBoolean();

        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }
        return result;
    } catch (IOException ex) {
        zygoteState.close();
        throw new ZygoteStartFailedEx(ex);
    }
}

今ProcessStartResultを手に入れましたが、実はこの時点で新しいプロセスが起動されていますが、どこで起動したのでしょうか.この方法を見てください.ZygoteStateが必要です.これはZygoteProcessの内部クラスで、zygoteプロセスとの接続状態が含まれています.全部で2つあります.
/**
 * The state of the connection to the primary zygote.
 */
private ZygoteState primaryZygoteState;

/**
 * The state of the connection to the secondary zygote.
 */
private ZygoteState secondaryZygoteState;

OpenZygoteSocketIfNeededメソッドを見て、Zygoteプロセスとsocket接続を確立しようとします.socketも通信方式です.primaryZygoteStateが空か閉じた後、接続を確立しようとします.このZygoteStateマッチングは直接使用に戻り、不一致はsecondaryZygoteState接続を使用し続けます.両方が一致しないか、空になっていません.接続していません.とにかくここには使えるsocket接続が必要です.このZygoteState接続状態を取得すると書き込み操作が可能になり、接続を確立するZygoteプロセスがこの情報を読み取るのですが、どちらで読み取れますか?下を見続けます.
/**
 * Tries to open socket to Zygote process if not already open. If
 * already open, does nothing.  May block and retry.  Requires that mLock be held.
 */
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");

    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
        try {
            primaryZygoteState = ZygoteState.connect(mSocket);
        } 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(mSecondarySocket);
        } 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);
}

zygoteは起動後にsocketリスニング機能をオンにし、リスニングにはプロセスの作成要求が必要であり、zygoteプロセスがいつこのsocketをオンにするかについてはzygoteの起動プロセスを見る必要がある.ここで私たちが関心を持っているのは主に3つのクラスです.ZygoteInit.java ZygoteServer.java ZygoteConnection.java
以下から抜粋:https://blog.csdn.net/luoshengyang/article/details/6768304AndroidシステムはLinuxカーネルに基づいていることを知っていますが、Linuxシステムでは、すべてのプロセスがinitプロセスの子孫プロセスであり、つまり、すべてのプロセスが直接または間接的にinitプロセスforkから出ていることを知っています.Zygoteプロセスも例外ではありません.システムが起動したプロセスで、initプロセスによって作成されます.システムでスクリプトsystem/core/rootdir/initを起動します.rcファイル内
Zygoteプロセスが起動するとZygoteInitのmainメソッドが呼び出されますが、Zygote起動プロセスについてはあまり言いたくありません.興味があれば、彼のソースコードを見てみましょう.ここではzygoteServerを見てみましょう.runSelectLoop(abiList);注記socket接続を受け入れる
ZygoteInit.java
public static void main(String argv[]) {
    ZygoteServer zygoteServer = new ZygoteServer();
    // Mark zygote start. This ensures that thread creation will throw
    // an error.
    ZygoteHooks.startZygoteNoThreadCreation();
    // Zygote goes into its own process group.
    try {
        Os.setpgid(0, 0);
    } catch (ErrnoException ex) {
        throw new RuntimeException("Failed to setpgid(0,0)", ex);
    }
    try {
        ...
        Log.i(TAG, "Accepting command socket connections");
        zygoteServer.runSelectLoop(abiList);
        zygoteServer.closeServerSocket();
    } catch (Zygote.MethodAndArgsCaller caller) {
        caller.run();
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        zygoteServer.closeServerSocket();
        throw ex;
    }
}

ZygoteServer.java
/**
 * Runs the zygote process's select loop. Accepts new connections as
 * they happen, and reads commands from connections one spawn-request's
 * worth at a time.
 *
 * @throws Zygote.MethodAndArgsCaller in a child process when a main()
 * should be executed.
 */
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
    ArrayList fds = new ArrayList();
    ArrayList peers = new ArrayList();
    fds.add(mServerSocket.getFileDescriptor());
    peers.add(null);
    while (true) {
        StructPollfd[] pollFds = new StructPollfd[fds.size()];
        for (int i = 0; i < pollFds.length; ++i) {
            pollFds[i] = new StructPollfd();
            pollFds[i].fd = fds.get(i);
            pollFds[i].events = (short) POLLIN;
        }
        try {
            Os.poll(pollFds, -1);
        } catch (ErrnoException ex) {
            throw new RuntimeException("poll failed", ex);
        }
        for (int i = pollFds.length - 1; i >= 0; --i) {
            if ((pollFds[i].revents & POLLIN) == 0) {
                continue;
            }
            if (i == 0) {
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                boolean done = peers.get(i).runOnce(this);
                if (done) {
                    peers.remove(i);
                    fds.remove(i);
                }
            }
        }
    }
}

次にZygoteConnectionクラスを見て、socketから情報を読み出し、成功するとサブプロセスが成功forkされ、失敗投異常を示す.新しいプロセス接続要求がある場合、Zygoteプロセスを起動し、ZygoteConnectionのrunOnceという方法を実行します.
/**
 * Reads one start command from the command socket. If successful,
 * a child is forked and a {@link Zygote.MethodAndArgsCaller}
 * exception is thrown in that child while in the parent process,
 * the method returns normally. On failure, the child is not
 * spawned and messages are printed to the log and stderr. Returns
 * a boolean status value indicating whether an end-of-file on the command
 * socket has been encountered.
 * 
 * @return false if command socket should continue to be read from, or
 * true if an end-of-file has been encountered.
 * @throws Zygote.MethodAndArgsCaller trampoline to invoke main()
 * method in child process
 */
boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {

    String args[];
    Arguments parsedArgs = null;
    FileDescriptor[] descriptors;

    try {
        //   readArgumentList()       ZygoteProgress  BufferedWriter writer = zygoteState.writer
        //   writer.write(arg);    
        //
        args = readArgumentList();
        descriptors = mSocket.getAncillaryFileDescriptors();
    } catch (IOException ex) {
        Log.w(TAG, "IOException on command socket " + ex.getMessage());
        closeSocket();
        return true;
    }

    ...

    int pid = -1;
    FileDescriptor childPipeFd = null;
    FileDescriptor serverPipeFd = null;

    try {
        ...
        //    fork       pid
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                parsedArgs.appDataDir);
    } 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) {
            //    pid 0             ,         
            zygoteServer.closeServerSocket();
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;
            handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

            // should never get here, the child is expected to either
            // throw Zygote.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);
    }
}

追跡を続けるforkAndSpecializeは最後にZygoteクラスのnativeForkAndSpecializeメソッドに着いたことを発見し、ここで呼び出されたのは最下位のc/c++コードである.ここで注意しなければならないのは、AndroidもLinuxシステムに属しているので、AndroidのZygoteプロセスのforkプロセスもLinuxシステムのプロセスforkプロセスであり、Linuxのプロセスforkについてあまり理解していないため、私はここで直接結論を言うしかありません.それはpid=Zygoteを実行することです.forkAndSpecializeという方法は,ここでは実際には2つのプロセス,すなわち1回に2回の戻りを実行し,2回の戻りは2つのプロセスで行われる.一つはサブプロセスであるアプリケーションプロセスであり,一つは元のZygoteのプロセスであり,ここでpid=Zygoteである.forkAndSpecializeは2回実行され、1回はサブプロセスで、pid=0はサブプロセスの作成に成功したことを示します.一度はZygoteプロセスでpidが0でなく0でない場合は異常の場合もあるが,種の異常の場合はまず考慮しない.
cppファイルの分析については、こちらを参考にhttps://www.2cto.com/kf/201607/527963.htmlnativeForkAndSpecialize()メソッドが最終的に呼び出されたのはcom_です.android_internal_os_Zygote.cppのcom_android_internal_os_Zygote_nativeForkAndSpecialize()メソッド、リンクはこちらhttps://android.googlesource.com/platform/frameworks/base/+/android-cts-8.0_r8/core/jni/com_android_internal_os_Zygote.cpp
native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags,
          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
          int[] fdsToIgnore, String instructionSet, String appDataDir);

com_android_internal_os_Zygote.cppファイル
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
        JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
        jint debug_flags, jobjectArray rlimits,
        jint mount_external, jstring se_info, jstring se_name,
        jintArray fdsToClose,
        jintArray fdsToIgnore,
        jstring instructionSet, jstring appDataDir) {
    ...
    return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
            rlimits, capabilities, capabilities, mount_external, se_info,
            se_name, false, fdsToClose, fdsToIgnore, instructionSet, appDataDir);
}

プロセスに関するforkプロセスはすべてjniのcppファイルで、ここでは深く入り込まないで、興味があれば上のリンク分析のもっと多いことを見てみましょう.次に、上記の2つのプロセスの戻りを考え続け、どのように行ったのかを考えて、まずZygoteプロセス、すなわちpidが0でない場合を考えてみると、handleParentProcの方法はsocketを通じてpidを返すことであることがわかります.
//  Zygote      
private boolean handleParentProc(int pid,
        FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {

    ...

    try {
        mSocketOutStream.writeInt(pid);
        mSocketOutStream.writeBoolean(usingWrapper);
    } catch (IOException ex) {
        Log.e(TAG, "Error writing to command socket", ex);
        return true;
    }

    return false;
}

次に、サブプロセスでどのような処理が行われているかを見て、handleChildProcメソッド、parsedArgsに入ります.invokeWith != nullはWrapperInitを実行する.execApplication、これはinvokeWithから何が伝わってきたのか見てみましょう
//             
private void handleChildProc(Arguments parsedArgs,
        FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
        throws Zygote.MethodAndArgsCaller {
    /**
     * By the time we get here, the native code has closed the two actual Zygote
     * socket connections, and substituted /dev/null in their place.  The LocalSocket
     * objects still need to be closed properly.
     */

    closeSocket();
    if (descriptors != null) {
        try {
            Os.dup2(descriptors[0], STDIN_FILENO);
            Os.dup2(descriptors[1], STDOUT_FILENO);
            Os.dup2(descriptors[2], STDERR_FILENO);

            for (FileDescriptor fd: descriptors) {
                IoUtils.closeQuietly(fd);
            }
            newStderr = System.err;
        } catch (ErrnoException ex) {
            Log.e(TAG, "Error reopening stdio", ex);
        }
    }

    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }

    // End of the postFork event.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    if (parsedArgs.invokeWith != null) {
        WrapperInit.execApplication(parsedArgs.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                VMRuntime.getCurrentInstructionSet(),
                pipeFd, parsedArgs.remainingArgs);
    } else {
        ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
                parsedArgs.remainingArgs, null /* classLoader */);
    }
}

ActivityManagerServiceのstartProcessLockedメソッドでは、このinvokeWithのデフォルトはnullで、これはDebuggable appsのときに使われるはずなので、ZygoteInitを直接考慮します.zygoteInitの場合
String invokeWith = null;
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
    // Debuggable apps may include a wrapper script with their library directory.
    String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
    StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
    try {
        if (new File(wrapperFileName).exists()) {
            invokeWith = "/system/bin/logwrapper " + wrapperFileName;
        }
    } finally {
        StrictMode.setThreadPolicy(oldPolicy);
    }
}

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

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

        RuntimeInit.commonInit();
        ZygoteInit.nativeZygoteInit();
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

ZygoteInit.nativeZygoteInit();中にはc++コードがあり、プロセスの初期化作業を実行するので、先に見ないで、RuntimeInitを見てみましょう.アプリケーションInitメソッド
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws Zygote.MethodAndArgsCaller {
    ...
    // Remaining arguments are passed to the start class's static main
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

/**
 * Invokes a static "main(argv[]) method on class "className".
 * Converts various failing exceptions into RuntimeExceptions, with
 *   className     main  ,    main      ?
 *     ActivityThead main  ,         
 * 0xa 0xb    ,           
 * @param className Fully-qualified class name
 * @param argv Argument vector for main()
 * @param classLoader the classLoader to load {@className} with
 */
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
        throws Zygote.MethodAndArgsCaller {
    Class> cl;

    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }

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

    int modifiers = m.getModifiers();
    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 Zygote.MethodAndArgsCaller(m, argv);
    //  MethodAndArgsCaller     ,             main  
}
public static class MethodAndArgsCaller extends Exception
        implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

ここではActivity Thread mainメソッドが開始された場所に到着しました.このmainメソッドには、有名なLooperを含む多くのappの初期化作業が行われています.prepareMainLooper();そしてLooper.loop(); そして後の件はActivityカテゴリーのhandlerに任せました.ActivityThread.java
public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    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);

    Environment.initForCurrentUser();

    // Set the reporter for event logging in libcore
    EventLogger.setReporter(new EventLoggingReporter());

    // Make sure TrustedCertificateStore looks in the right place for CA certificates
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);

    Process.setArgV0("");

    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

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

続けて下を見て、threadを実行しました.attach(false);入力パラメータsystemはfalseでmgrを実行する.attachApplication(mAppThread);,またプロセス通信方式で呼び出されたAMSのattachApplicationメソッド

 private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        ViewRootImpl.addFirstDrawHandler(new Runnable() {
            @Override
            public void run() {
                ensureJitEnabled();
            }
        });
        android.ddm.DdmHandleAppName.setAppName("",
                                                UserHandle.myUserId());
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ...
    } 

    ...
}
//ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {

    // Find the application record that is being attached...  either via
    // the pid if we are running in multiple processes, or just pull the
    // next app record if we are emulating process with anonymous threads.
    ProcessRecord app;
    ...

    app.makeActive(thread, mProcessStats);
    app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
    app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
    app.forcingToImportant = null;
    updateProcessForegroundLocked(app, false, false);
    app.hasShownUi = false;
    app.debugging = false;
    app.cached = false;
    app.killedByAm = false;
    app.killed = false;

    ...
    try {
        ...

        mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
        //bindApplication   application         
        if (app.instr != null) {
            thread.bindApplication(processName, appInfo, providers,
                    app.instr.mClass,
                    profilerInfo, app.instr.mArguments,
                    app.instr.mWatcher,
                    app.instr.mUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(getGlobalConfiguration()), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial);
        } else {
            thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                    null, null, null, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(getGlobalConfiguration()), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial);
        }

        checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
        updateLruProcessLocked(app, false, null);
        checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    } catch (Exception e) {
        // todo: Yikes!  What should we do?  For now we will try to
        // start another process, but that could easily get us in
        // an infinite loop of restarting processes...
        Slog.wtf(TAG, "Exception thrown during bind of " + app, e);

        app.resetPackageList(mProcessStats);
        app.unlinkDeathRecipient();
        startProcessLocked(app, "bind fail", processName);
        return false;
    }

    // Remove this record from the list of starting applications.
    mPersistentStartingProcesses.remove(app);
    if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
            "Attach application locked removing on hold: " + app);
    mProcessesOnHold.remove(app);

    boolean badApp = false;
    boolean didSomething = false;

    // See if the top visible activity is waiting to run in this process...
    if (normalMode) {
        try {
            //attachApplicationLocked   activity
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }

    // Find any services that should be running in this process...
    if (!badApp) {
        try {
            didSomething |= mServices.attachApplicationLocked(app, processName);
            checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
            badApp = true;
        }
    }

    // Check if a next-broadcast receiver is in this process...
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        try {
            didSomething |= sendPendingBroadcastsLocked(app);
            checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
        } catch (Exception e) {
            // If the app died trying to launch the receiver we declare it 'bad'
            Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
            badApp = true;
        }
    }

    // Check whether the next backup agent is in this process...
    if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
                "New app is backup target, launching agent for " + app);
        notifyPackageUse(mBackupTarget.appInfo.packageName,
                         PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
        try {
            thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                    compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                    mBackupTarget.backupMode);
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
            badApp = true;
        }
    }

    if (badApp) {
        app.kill("error during init", true);
        handleAppDiedLocked(app, false, true);
        return false;
    }

    if (!didSomething) {
        updateOomAdjLocked();
        checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
    }

    return true;
}

A t t a c h A p r i c ationLockedメソッドでは、realStartActivity Lockedメソッドが表示されます.realStartActivity Lockedメソッドで最終的に呼び出されたのはappです.thread.scheduleLaunchActivity.
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFocusedStack(stack)) {
                continue;
            }
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
            final ActivityRecord top = stack.topRunningActivityLocked();
            final int size = mTmpActivityList.size();
            for (int i = 0; i < size; i++) {
                final ActivityRecord activity = mTmpActivityList.get(i);
                if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                        && processName.equals(activity.processName)) {
                    try {
                        if (realStartActivityLocked(activity, app,
                                top == activity /* andResume */, true /* checkConfig */)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                                + top.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }
    return didSomething;
}

リファレンス接続
参考接続についてはあまりにも多すぎますので、列挙しきれないかもしれませんが、ご了承ください
https://blog.csdn.net/luoshengyang/article/details/6747696 https://www.2cto.com/kf/201607/527963.html https://blog.csdn.net/tfygg/article/details/53563638 http://www.cloudchou.com/android/post-805.html https://juejin.im/entry/576e42f9128fe1005a27fc11 http://mouxuejie.com/blog/2016-03-12/activity-launch-analysis/