从startActivity一直到可见

从Launcher启动app的LauncherActivity

  1. Launcher.startActivity或者Context.startActivity【ContextImpl.startActivity 】

  2. 都会调用到Instrumentation.execStartActivity

    函数定义在frameworks/base/core/java/android/app/Instrumentation.java文件中:

    public ActivityResult execStartActivity(            Context who, IBinder contextThread, IBinder token, Activity target,            Intent intent, int requestCode, Bundle options) {        ......        IApplicationThread whoThread = (IApplicationThread) contextThread;        ......        if (mActivityMonitors != null) {            ......        }        try {            ......            int result = ActivityManager.getService()                .startActivity(whoThread, who.getBasePackageName(), intent,                        intent.resolveTypeIfNeeded(who.getContentResolver()),                        token, target != null ? target.mEmbeddedID : null,                        requestCode, 0, null, options);            ......        } catch (RemoteException e) {            throw new RuntimeException("Failure from system", e);        }        return null;    }

    ActivityManager.getService()返回ActivityManagerService的远程接口,通过Binder调用,进入AMS中。

    以上是在Launcher进程中

  3. ActivityManagerService.startActivity

    函数在\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java文件中:

    public final int startActivity(IApplicationThread caller, String callingPackage,            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,                resultWho, requestCode, startFlags, profilerInfo, bOptions,                UserHandle.getCallingUserId());    }

    简单调用ActivityManagerService.startActivityAsUser

  4. ActivityManagerService.startActivityAsUser

    函数在\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java文件中

    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {        enforceNotIsolatedCaller("startActivity");        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),                userId, false, ALLOW_FULL_ONLY, "startActivity", null);        // TODO: Switch to user app stacks here.        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,                profilerInfo, null, null, bOptions, false, userId, null, null,                "startActivityAsUser");    }

    简单地将操作转发给成员变量mActivityStarter的startActivityMayWait函数,这里的mActivityStarter的类型为com.android.server.am.ActivityStarter

  5. ActivityStarter.startActivityMayWait

    \frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java

  6. ActivityStarter.startActivityLocked

    \frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java

    简单调用ActivityStarter.startActivity

  7. ActivityStarter.startActivity

    \frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java

    一堆检查操作后,直接调用ActivityStarter.startActivity

  8. ActivityStarter.startActivity

    \frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java

    直接调用ActivityStarter.startActivityUnchecked

  9. ActivityStarter.startActivityUnchecked

    \frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java

    这里检查了权限、任务栈、启动模式

  10. ActivityStarter.setTargetStackAndMoveToFrontIfNeeded

    \frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java

    /**     * Figure out which task and activity to bring to front when we have found an existing matching     * activity record in history. May also clear the task if needed.     * @param intentActivity Existing matching activity.     * @return {@link ActivityRecord} brought to front.     */

    注释翻译:在我们找到历史记录中的现有匹配活动记录时,确定要将哪些任务和活动带到前面。 如果需要,也可以清除任务 。

    intentActivity.showStartingWindow显示一个starting window

  11. ActivityStack.moveTaskToFrontLocked

    \frameworks\base\services\core\java\com\android\server\am\ActivityStack.java

  12. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

    \frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java

  13. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

    \frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java

  14. ActivityStack.resumeTopActivityUncheckedLocked

    \frameworks\base\services\core\java\com\android\server\am\ActivityStack.java

  15. ActivityStack.resumeTopActivityInnerLocked

    \frameworks\base\services\core\java\com\android\server\am\ActivityStack.java

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {        ......        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);        ......        final boolean userLeaving = mStackSupervisor.mUserLeaving;        ......        final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0 && !lastResumedCanPip;        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);        if (mResumedActivity != null) {            pausing |= startPausingLocked(userLeaving, false, next, false);        }        if (pausing && !resumeWhilePausing) {            ......            return true;        } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&                mStackSupervisor.allResumedActivitiesComplete()) {            ......            return true;        }        ......        if (prev != null && prev != next) {            ......        }        ......        boolean anim = true;        if (prev != null) {            ......        } else {           ......        }        ......        ActivityStack lastStack = mStackSupervisor.getLastStack();        if (next.app != null && next.app.thread != null) {            ......            setResumedActivityLocked(next, "resumeTopActivityInnerLocked");            ......            boolean notUpdated = true;            if (mStackSupervisor.isFocusedStack(this)) {                ......                notUpdated = !mService.updateDisplayOverrideConfigurationLocked(config, next, false /* deferResume */, mDisplayId);            }            if (notUpdated) {                .....                ActivityRecord nextNext = topRunningActivityLocked();                ......                if (nextNext != next) {                    // Do over!                    mStackSupervisor.scheduleResumeTopActivities();                }                if (!next.visible || next.stopped) {                    next.setVisibility(true);                }                next.completeResumeLocked();                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();                return true;            }            try {                ......                if (next.newIntents != null) {                    next.app.thread.scheduleNewIntent(                            next.newIntents, next.appToken, false /* andPause */);                }                ......                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,                        mService.isNextTransitionForward(), resumeAnimOptions);                ......            } catch (Exception e) {                ......                return true;            }            // From this point on, if something goes wrong there is no way            // to recover the activity.            try {                next.completeResumeLocked();            } catch (Exception e) {                ......                return true;            }        } else {            // Whoops, need to restart this activity!            ......            mStackSupervisor.startSpecificActivityLocked(next, true, true);        }        return true;    }

    此处调用mStackSupervisor.pauseBackStacks一直等着结果回来以后,继续向下执行,这个结果是pausing =true。ActivityStackSupervisor.pauseBackStacks又调用ActivityStack.startPausingLocked里面会将mResumedActivity置为null,所以pausing |= startPausingLocked(userLeaving, false, next, false)不会执行到。resumeTopActivityInnerLocked第一次调用的时候,pausing && !resumeWhilePausing = true,所以,当在if (pausing && !resumeWhilePausing)代码块中直接return true了,后面代码不会执行。

    startPausingLocked最终会调用到completePauseLocked,而completePauseLocked最终又会间接调用到resumeTopActivityInnerLocked。通过completePauseLocked最终间接调用到resumeTopActivityInnerLocked的时候,会调用到mStackSupervisor.startSpecificActivityLocked(next, true, true)。也就是这个过程中,此时resumeTopActivityInnerLocked已经调用了两次了.

  16. ActivityStackSupervisor.pauseBackStacks

    \frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java

    boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {        boolean someActivityPaused = false;        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {                final ActivityStack stack = stacks.get(stackNdx);                if (!isFocusedStack(stack) && stack.mResumedActivity != null) {                    if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +                            " mResumedActivity=" + stack.mResumedActivity);                    someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,                            dontWait);                }            }        }        return someActivityPaused;    }

    此处调用stack.startPausingLocked,返回someActivityPaused=true

  17. ActivityStack.startPausingLocked

    \frameworks\base\services\core\java\com\android\server\am\ActivityStack.java

    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,            ActivityRecord resuming, boolean pauseImmediately) {        ......        ActivityRecord prev = mResumedActivity;        ......        mResumedActivity = null;        mPausingActivity = prev;        mLastPausedActivity = prev;        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;        prev.state = ActivityState.PAUSING;        prev.getTask().touchActiveTime();        clearLaunchTime(prev);        ......        if (prev.app != null && prev.app.thread != null) {            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);            try {                ......                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,                        userLeaving, prev.configChangeFlags, pauseImmediately);            } catch (Exception e) {                ......            }        } else {            ......        }        ......        if (mPausingActivity != null) {            ......            if (pauseImmediately) {                // If the caller said they don't want to wait for the pause, then complete                // the pause now.                completePauseLocked(false, resuming);                return false;            } else {                schedulePauseTimeout(prev);                return true;            }        } else {            // This activity failed to schedule the            // pause, so just treat it as being paused now.            if (resuming == null) {                mStackSupervisor.resumeFocusedStackTopActivityLocked();            }            return false;        }    }

    prev.app.thread.schedulePauseActivity通过ApplicationThread调用android.app.ActivityThread.H发送Handler消息在Launcher进程的主线程中调用handlePauseActivity。

    从上面调用得知pauseImmediately=false,会调用schedulePauseTimeout(prev),

    pause超时后,发送handler消息立刻执行ActivityStack.activityPausedLocked。

  18. ActivityThread.handlePauseActivity

    private void handlePauseActivity(IBinder token, boolean finished,            boolean userLeaving, int configChanges, boolean dontReport, int seq) {        ......        if (r != null) {            if (userLeaving) {                performUserLeavingActivity(r);            }            r.activity.mConfigChangeFlags |= configChanges;            performPauseActivity(token, finished, r.isPreHoneycomb(), handlePauseActivity");            ......            // Tell the activity manager we have paused.            if (!dontReport) {                try {                    ActivityManager.getService().activityPaused(token);                } catch (RemoteException ex) {                    throw ex.rethrowFromSystemServer();                }            }            mSomeActivitiesChanged = true;        }    }

    ActivityManager.getService().activityPaused(token),此处调用AMS的activityPaused

  19. ActivityManagerService.activityPaused

    @Override    public final void activityPaused(IBinder token) {        final long origId = Binder.clearCallingIdentity();        synchronized(this) {            ActivityStack stack = ActivityRecord.getStackLocked(token);            if (stack != null) {                stack.activityPausedLocked(token, false);            }        }        Binder.restoreCallingIdentity(origId);    }

    此处调用ActivityStack.activityPausedLocked

  20. ActivityStack.activityPausedLocked

    \frameworks\base\services\core\java\com\android\server\am\ActivityStack.java

    final void activityPausedLocked(IBinder token, boolean timeout) {        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,            "Activity paused: token=" + token + ", timeout=" + timeout);        final ActivityRecord r = isInStackLocked(token);        if (r != null) {            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);            if (mPausingActivity == r) {                ......                try {                    completePauseLocked(true /* resumeNext */, null /* resumingActivity */);                } finally {                    mService.mWindowManager.continueSurfaceLayout();                }                return;            } else {                ......            }        }        ......    }

    此处调用ActivityStack.completePauseLocked

  21. ActivityStack.completePauseLocked

    private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {        ActivityRecord prev = mPausingActivity;        if (prev != null) {            ......            mPausingActivity = null;        }        if (resumeNext) {            final ActivityStack topStack = mStackSupervisor.getFocusedStack();            if (!mService.isSleepingOrShuttingDownLocked()) {                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);            } else {                mStackSupervisor.checkReadyForSleepLocked();                ActivityRecord top = topStack.topRunningActivityLocked();                if (top == null || (prev != null && top != prev)) {                    // If there are no more activities available to run, do resume anyway to start                    // something. Also if the top activity on the stack is not the just paused                    // activity, we need to go ahead and resume it to ensure we complete an                    // in-flight app switch.                    mStackSupervisor.resumeFocusedStackTopActivityLocked();                }            }        }        if (prev != null) {            ......        }        ......    }

    这里调用了mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);最终由调用到ActivityStack.resumeTopActivityInnerLocked,然后继而调用mStackSupervisor.startSpecificActivityLocked(next, true, true);**这一轮调用不是刚开始15那轮调用,此时15那轮调用还没结束呢!**一直等pause的全部逻辑结束后,ActivityStack.resumeTopActivityInnerLocked的第一轮调用中才到if (pausing && !resumeWhilePausing)中return true;

    ActivityStack.resumeTopActivityInnerLocked两次调用的调用栈如下:


22. ActivityStackSupervisor.startSpecificActivityLocked

\frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java```javavoid 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启动,所以if代码块不会执行到。
  1. ActivityManagerService.startProcessLocked

    函数在\frameworks\base\services\core\java\com\android\server\am\startProcessLocked.java文件中:

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

    此处hostingType = “activity”

  2. ActivityManagerService.startProcessLocked

    函数在\frameworks\base\services\core\java\com\android\server\am\startProcessLocked.java文件中:

    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) {        ......        startProcessLocked(                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);        ......        return (app.pid != 0) ? app : null;    }

    此处hostingType = “activity”

  3. ActivityManagerService.startProcessLocked

    函数在\frameworks\base\services\core\java\com\android\server\am\startProcessLocked.java文件中:

    private final void startProcessLocked(ProcessRecord app, String hostingType,            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {        ......        try {            ......            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);                }            }                ......            ProcessStartResult startResult;            if (hostingType.equals("webview_service")) {                ......            } else {                startResult = Process.start(entryPoint,                        app.processName, uid, uid, gids, debugFlags, mountExternal,                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,                        app.info.dataDir, invokeWith, entryPointArgs);            }            ......        } catch (RuntimeException e) {            ......        }    }

    此处hostingType = “activity”。invokeWith = null。

  4. Process.start

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

    这里的processClass就是要启动的app的ActivityThread,最终会找到ActivityThread.main;

    invokeWith = null.

  5. ZygoteProcess.start

    \frameworks\base\core\java\android\os\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) {            ......        }    }

    这里的processClass就是要启动的app的ActivityThread,最终会找到ActivityThread.main

    invokeWith = null.

  6. ZygoteProcess.startViaZygote

    \frameworks\base\core\java\android\os\ZygoteProcess.java

    private Process.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 invokeWith,                                                      String[] extraArgs)                                                      throws ZygoteStartFailedEx {        ArrayList<String> argsForZygote = new ArrayList<String>();        ............        synchronized(mLock) {            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);        }    }

    把zygote进程fork子进程所需要的参数放入argsForZygote

  7. ZygoteProcess.zygoteSendArgsAndGetResult

    \frameworks\base\core\java\android\os\ZygoteProcess.java

    private static Process.ProcessStartResult zygoteSendArgsAndGetResult(            ZygoteState zygoteState, ArrayList<String> 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();            // Should there be a timeout on this?            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);        }    }

    通过socket和zygote进程通信,用BufferedWriter把参数写入socket传递给zygote进程,最后通过DataInputStream把zygote进程fork子进程的结果读出来.

    3~~29是在AMS即system_server进程

  8. ZygoteInit.main

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

    public static void main(String argv[]) {        ZygoteServer zygoteServer = new ZygoteServer();        ......        final Runnable caller;        try {            ......            caller = zygoteServer.runSelectLoop(abiList);        } catch (Throwable ex) {            Log.e(TAG, "System zygote died with exception", ex);            throw ex;        } finally {            zygoteServer.closeServerSocket();        }        // We're in the child process and have exited the select loop. Proceed to execute the        // command.        if (caller != null) {            caller.run();        }    }

    Zygote进程是在系统启动后就被启动的进程,初始化在ZygoteInit.main中完成,ygoteServer.runSelectLoop启动一个死循环,就是为了fork进程,这里会取出ams发送来的参数,fork一个子进程,此处即app进程

  9. ZygoteServer.runSelectLoop

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

    Runnable runSelectLoop(String abiList) {        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();        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 {                    try {                        ZygoteConnection connection = peers.get(i);                        final Runnable command = connection.processOneCommand(this);                        if (mIsForkChild) {                            // We're in the child. We should always have a command to run at this                            // stage if processOneCommand hasn't called "exec".                            if (command == null) {                                throw new IllegalStateException("command == null");                            }                            return command;                        } else {                            // We're in the server - we should never have any commands to run.                            if (command != null) {                                throw new IllegalStateException("command != null");                            }                            // We don't know whether the remote side of the socket was closed or                            // not until we attempt to read from it from processOneCommand. This shows up as                            // a regular POLLIN event in our regular processing loop.                            if (connection.isClosedByPeer()) {                                connection.closeSocket();                                peers.remove(i);                                fds.remove(i);                            }                        }                    } catch (Exception e) {                       ......                        } else {                            // We're in the child so any exception caught here has happened post                            // fork and before we execute ActivityThread.main (or any other main()                            // method). Log the details of the exception and bring down the process.                            Log.e(TAG, "Caught post-fork exception in child process.", e);                            throw e;                        }                    }                }            }        }    }

    zygote进程通过ZygoteServer.runSelectLoop启动一个死循环,就是为了fork进程,

    划重点:final Runnable command = connection.processOneCommand(this);

  10. ZygoteConnection.processOneCommand

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

    Runnable processOneCommand(ZygoteServer zygoteServer) {        ......        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,                parsedArgs.appDataDir);        try {            if (pid == 0) {                // in child                zygoteServer.setForkChild();                //void setForkChild() {           //mIsForkChild = true;       //}                zygoteServer.closeServerSocket();                IoUtils.closeQuietly(serverPipeFd);                serverPipeFd = null;                return handleChildProc(parsedArgs, descriptors, childPipeFd);            } else {                // In the parent. A pid < 0 indicates a failure and will be handled in                // handleParentProc.                IoUtils.closeQuietly(childPipeFd);                childPipeFd = null;                handleParentProc(pid, descriptors, serverPipeFd);                return null;            }        } finally {            IoUtils.closeQuietly(childPipeFd);            IoUtils.closeQuietly(serverPipeFd);        }    }

    Zygote.forkAndSpecialize刚刚fork出来的子进程会完全继承父进程的所有状态,包括运行时、文件、资源等,所以子进程也有while循环,也会在main方法里没出来;

    pid == 0是子进程,zygoteServer.setForkChild()标记为子进程,通过ZygoteConnectionhandleChildProc返回一个Runnable,这样就跳出while循环,并且把runnable return出去,在ZygoteInit.main中赋给了caller,caller调用run方法,最终调用到ActivityThread.main

    ,这个runnable由ZygoteInit.zygoteInit调用RuntimeInit.applicationInit创建

    补充:

    linux创建子进程–fork()方法

    https://www.cnblogs.com/xingzc/p/5988069.html

    (1)fork()的定义
    fork()函数是Unix中派生新进程的唯一方法,声明如下:
    我们需要理解的是,调用一次fork()方法,该方法会返回两次。一次是在调用进程(也就是派生出的子进程的父进程)中返回一次,返回值是新派生的进程的进程ID。一次是在子进程中返回,返回值是0,代表当前进程为子进程。如果返回值为-1的话,则代表在派生新进程的过程中出错。
    那么在程序中,我们就可以根据此返回值来判断当前进程是父进程还是子进程,来实现一些具体的操作。
    (2)fork()的实质过程
    父进程中在调用fork()派生新进程,实际上相当于创建了进程的一个拷贝;即在fork()之前的进程拥有的资源会被复制到新的进程中去。网络服务器在处理并发请求时,也可以采取这种派生新进程的方式: 父进程调用accept()后调用fork()来处理每一个连接。那么,所接受的已连接的套接口随后就在父子进程中共享。通常来说,子进程会在这连接套接口中读和写操作,父进程则关闭这个已连的套接口(可以参考:http://blog.csdn.net/moxiaomomo/article/details/6791763)
    (3)fork()的用法
    fork()有两个典型用法:(1)一个进程进行自身的复制,这样每个副本可以独立的完成具体的操作,在多核处理器中可以并行处理数据。这也是网络服务器的其中一个典型用途,多进程处理多连接请求。 (2)一个进程想执行另一个程序。比如一个软件包含了两个程序,主程序想调起另一个程序的话,它就可以先调用fork来创建一个自身的拷贝,然后通过exec函数来替换成将要运行的新程序。

  11. ZygoteConnectionhandleChildProc

    private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,            FileDescriptor pipeFd) {        .......        if (parsedArgs.invokeWith != null) {            ......        } else {            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */);        }    }

    从20,21可知,parsedArgs.invokeWith = null

  12. ZygoteInit.zygoteInit

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

    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {        ......        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);    }

    String[] argv里面就是ActivityThread.main相关信息

  13. RuntimeInit.applicationInit

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

    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,            ClassLoader classLoader) {        ......        // Remaining arguments are passed to the start class's static main        return findStaticMain(args.startClass, args.startArgs, classLoader);    }

    方法名很直观,应用初始化

  14. RuntimeInit.findStaticMain

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

    private static Runnable findStaticMain(String className, String[] argv,            ClassLoader classLoader) {        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.         */        return new MethodAndArgsCaller(m, argv);    }        static class MethodAndArgsCaller implements Runnable {        /** method to call */        private final Method mMethod;        /** argument array */        private final String[] mArgs;        public MethodAndArgsCaller(Method method, String[] args) {            mMethod = method;            mArgs = args;        }        public void run() {            try {                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);            }        }    }

    这里就找到了app进程的ActivityThread.main,最终在ZygoteInit.main中调用.

  15. ActivityThread.main

    public static void main(String[] args) {        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");        SamplingProfilerIntegration.start();        CloseGuard.setEnabled(false);        Environment.initForCurrentUser();        EventLogger.setReporter(new EventLoggingReporter());        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");    }

    ActivityThread.main中在启动主消息循环之前,创建了一个ActivityThread对象并调用attach方法,ActivityThread对象创建的时候,ActivityThread对象的成员变量ApplicationThread 对象立刻创建final ApplicationThread mAppThread = new ApplicationThread();。

  16. ActivityThread.attach

    private void attach(boolean system) {        sCurrentActivityThread = this;        mSystemThread = system;        if (!system) {            ......            final IActivityManager mgr = ActivityManager.getService();            try {                mgr.attachApplication(mAppThread);            } catch (RemoteException ex) {                throw ex.rethrowFromSystemServer();            }            ......        } else {            ......        }        ......    }

    将app进程的ApplicationThread对象mAppThread绑定到AMS

  17. ActivityManagerService.attachApplication

    @Override    public final void attachApplication(IApplicationThread thread) {        synchronized (this) {            ......            attachApplicationLocked(thread, callingPid);            ......        }    }
  18. ActivityManagerService.attachApplicationLocked

    private final boolean attachApplicationLocked(IApplicationThread thread,            int pid) {        ......        try {            ......            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);            }            ......        } catch (Exception e) {            ......            return false;        }        ......        if (normalMode) {            try {                if (mStackSupervisor.attachApplicationLocked(app)) {                    didSomething = true;                }            } catch (Exception e) {                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);                badApp = true;            }        }        ......        return true;    }

    AMS通过Binder对象即ApplicationThread对象thread,调用.ActivityThread.ApplicationThread.bindApplication,紧接着调用mStackSupervisor.attachApplicationLocked(app),ActivityStackSupervisor.attachApplicationLocked里面调用了ActivityStackSupervisor.realStartActivityLocked

  19. ActivityThread.ApplicationThread.bindApplication

    public final void bindApplication(String processName, ApplicationInfo appInfo,        List<ProviderInfo> providers, ComponentName instrumentationName,        ProfilerInfo profilerInfo, Bundle instrumentationArgs,        IInstrumentationWatcher instrumentationWatcher,        IUiAutomationConnection instrumentationUiConnection, int debugMode,        boolean enableBinderTracking, boolean trackAllocation,        boolean isRestrictedBackupMode, boolean persistent, Configuration config,        CompatibilityInfo compatInfo, Map services, Bundle coreSettings,        String buildSerial) {    ......    sendMessage(H.BIND_APPLICATION, data);}

    case BIND_APPLICATION:里调用handleBindApplication

  20. ActivityThread.handleBindApplication

    private void handleBindApplication(AppBindData data) {    ......    final InstrumentationInfo ii;    ......    // Continue loading instrumentation.        if (ii != null) {            ......            try {                final ClassLoader cl = instrContext.getClassLoader();                mInstrumentation = (Instrumentation)                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();            } catch (Exception e) {               ......            }            ......        } else {            mInstrumentation = new Instrumentation();        }    ......    try {        // If the app is being launched for full backup or restore, bring it up in        // a restricted environment with the base application class.        Application app = data.info.makeApplication(data.restrictedBackupMode, null);        ......        try {            mInstrumentation.onCreate(data.instrumentationArgs);        }        catch (Exception e) {            ......        }        try {            mInstrumentation.callApplicationOnCreate(app);        } catch (Exception e) {            if (!mInstrumentation.onException(app, e)) {                throw new RuntimeException(                    "Unable to create application " + app.getClass().getName()                    + ": " + e.toString(), e);            }        }    } finally {        StrictMode.setThreadPolicy(savedPolicy);    }    ......}

    初始化ActivityThread成员变量mInstrumentation;创建Application对象,并回调Application的onCreate,其实attachBaseContext在makeAppliaction就调用了.

  21. LoadedApk.makeApplication

    public Application makeApplication(boolean forceDefaultAppClass,        Instrumentation instrumentation) {    if (mApplication != null) {        return mApplication;    }.......    Application app = null;    String appClass = mApplicationInfo.className;    if (forceDefaultAppClass || (appClass == null)) {        appClass = "android.app.Application";    }    try {        java.lang.ClassLoader cl = getClassLoader();        ......        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);        app = mActivityThread.mInstrumentation.newApplication(                cl, appClass, appContext);        appContext.setOuterContext(app);    } catch (Exception e) {        .......    }    m......    if (instrumentation != null) {        try {            instrumentation.callApplicationOnCreate(app);        } catch (Exception e) {            if (!instrumentation.onException(app, e)) {                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                throw new RuntimeException(                    "Unable to create application " + app.getClass().getName()                    + ": " + e.toString(), e);            }        }    }    ......    return app;}

    如果Application对象已经创建,则直接返回;如果没有创建,则交由ActivityThread的成员变量mInstrumentation的方法newApplication创建;传过来的参数instrumentation=null,所以此处不会调用onCreate

  22. Instrumentation.newApplication

    static public Application newApplication(Class<?> clazz, Context context)        throws InstantiationException, IllegalAccessException,         ClassNotFoundException {    Application app = (Application)clazz.newInstance();    app.attach(context);    return app;}
  23. Application.attach

    final void attach(Context context) {    attachBaseContext(context);    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;}

    Application.attach里调用attachBaseContext(context);所以看出比onCreate执行的时机早。这些都是在ActivityThread的主消息循环中执行的。

    接下来回到AMS中的attachApplicationLocked中调用的mStackSupervisor.attachApplicationLocked(app)

  24. ActivityStackSupervisor.attachApplicationLocked

    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {    final String processName = app.processName;    boolean didSomething = false;    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {            final ActivityStack stack = stacks.get(stackNdx);            if (!isFocusedStack(stack)) {                continue;            }            ActivityRecord hr = stack.topRunningActivityLocked();            if (hr != null) {                if (hr.app == null && app.uid == hr.info.applicationInfo.uid                        && processName.equals(hr.processName)) {                    try {                        if (realStartActivityLocked(hr, app, true, true)) {                            didSomething = true;                        }                    } catch (RemoteException e) {                        ......                        throw e;                    }                }            }        }    }    ......    return didSomething;}

    这里调用了realStartActivityLocked

  25. ActivityStackSupervisor.realStartActivityLocked

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,        boolean andResume, boolean checkConfig) throws RemoteException {    ......    final ActivityStack stack = task.getStack();    try {        if (app.thread == null) {            throw new 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);        ......    } catch (RemoteException e) {        ......        throw e;    }    ......    return true;}

    这里通过AppliactionThread调用ActivityThread.ApplicationThread.scheduleLaunchActivity,通过ActivityThread.H调用到handleLaunchActivity

  26. ActivityThread.handleLaunchActivity

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {    .......    Activity a = performLaunchActivity(r, customIntent);    if (a != null) {        ......        handleResumeActivity(r.token, false, r.isForward,                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);        ......    } else {        ......    }}
  27. ActivityThread.performLaunchActivity

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        ActivityInfo aInfo = r.activityInfo;    if (r.packageInfo == null) {        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,                Context.CONTEXT_INCLUDE_CODE);    }    ComponentName component = r.intent.getComponent();    if (component == null) {        component = r.intent.resolveActivity(            mInitialApplication.getPackageManager());        r.intent.setComponent(component);    }    if (r.activityInfo.targetActivity != null) {        component = new ComponentName(r.activityInfo.packageName,                r.activityInfo.targetActivity);    }    ContextImpl appContext = createBaseContextForActivity(r);    Activity activity = null;    try {        java.lang.ClassLoader cl = appContext.getClassLoader();        activity = mInstrumentation.newActivity(                cl, component.getClassName(), r.intent);        StrictMode.incrementExpectedActivityCount(activity.getClass());        r.intent.setExtrasClassLoader(cl);        r.intent.prepareToEnterProcess();        if (r.state != null) {            r.state.setClassLoader(cl);        }    } catch (Exception e) {        ......    }    try {        Application app = r.packageInfo.makeApplication(false, mInstrumentation);        ......        if (activity != null) {            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());            Configuration config = new Configuration(mCompatConfiguration);            if (r.overrideConfig != null) {                config.updateFrom(r.overrideConfig);            }                        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) {                ......            }            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) {                    ......                }            }        }        r.paused = true;        mActivities.put(r.token, r);    } catch (SuperNotCalledException e) {        throw e;    } catch (Exception e) {        ......    }    return activity;}

    通过反射创建Activity对象,创建Activity的上下文信息,并通过attach方法将这些上下文信息设置到Activity中去,通过mInstrumentation的callActivityOnCreate调用Activity.onCreate,LauncherActivity就启动起来了,整个应用程序也启动起来了,但是此时还不可见。ActivityThread.handleLaunchActivity中还调用了handleResumeActivity

  28. ActivityThread.handleResumeActivity

    final void handleResumeActivity(IBinder token,        boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {    ......    r = performResumeActivity(token, clearHide, reason);    if (r != null) {        final Activity a = r.activity;        ......        if (r.window == null && !a.mFinished && willBeVisible) {            r.window = r.activity.getWindow();            View decor = r.window.getDecorView();            decor.setVisibility(View.INVISIBLE);            ViewManager wm = a.getWindowManager();            WindowManager.LayoutParams l = r.window.getAttributes();            a.mDecor = decor;            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;            l.softInputMode |= forwardBit;            if (r.mPreserveWindow) {                a.mWindowAdded = true;                r.mPreserveWindow = false;                // Normally the ViewRoot sets up callbacks with the Activity                // in addView->ViewRootImpl#setView. If we are instead reusing                // the decor view we have to notify the view root that the                // callbacks may have changed.                ViewRootImpl impl = decor.getViewRootImpl();                if (impl != null) {                    impl.notifyChildRebuilt();                }            }            if (a.mVisibleFromClient) {                if (!a.mWindowAdded) {                    a.mWindowAdded = true;                    wm.addView(decor, l);                } else {                    ......                }            }       ......        if (!r.activity.mFinished && willBeVisible                && r.activity.mDecor != null && !r.hideForNow) {            ......            if (r.activity.mVisibleFromClient) {                r.activity.makeVisible();            }        }        ......    } else {       ......    }}

    这里调用了performResumeActivity 和activity.makeVisible()

    makeVisible之后,Activity才真正可见并且可交互。

  29. Activity.makeVisible

    void makeVisible() {    if (!mWindowAdded) {        ViewManager wm = getWindowManager();        wm.addView(mDecor, getWindow().getAttributes());        mWindowAdded = true;    }    mDecor.setVisibility(View.VISIBLE);}



PS:感谢老罗的Android之旅

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

更多相关文章

  1. Android(安卓)为Notification加上一个进度条
  2. Android(安卓)bluetooth介绍(四): a2dp connect流程分析
  3. TextToSpeech 文本自动朗读
  4. Android数据库编程:SqLiteOpenHelper的使用
  5. Android之SimpleAdapter简单实例和SimpleAdapter参数说明
  6. Android(安卓)Service那些不得不说的事-之一
  7. ServiceManager Java 代理对象的获取
  8. S5PV210 Android(安卓)fimc驱动分析 - fimc_capture.c
  9. Android(安卓)关键字 收集

随机推荐

  1. android matrix使用和详细说明
  2. Android中HTTP请求中文乱码解决办法
  3. Android 自定义 spinner样式
  4. Android studio菜鸟开发————Radiogro
  5. 【Android】v7包Dialog使用
  6. android menu.addIntentOptions 添加动态
  7. 总结android中的.gradle文件写法及含义
  8. 精通Android3笔记--第十一章
  9. Android(安卓)网络显示图片 通过代理访问
  10. Mac系统Android(安卓)M源码编译并导入And