Android app启动流程(Activity启动过程)【基于Android 8.1】

从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
    mSupervisor.resolveActivity解析出ActivityInfo aInfo后,调用startActivityLocked

  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

    这里检查了权限、任务栈、启动模式
    (如果是从桌面冷启动APP,那么会因为getReusableIntentActivity方法返回的reusedActivity是null,则不执行10和11。调用 ActivityStack 的 startActivityLocked 方法 mTargetStack.startActivityLocked,此处将启动的 Activity 插入到栈顶部并showStartingWindow显示一个starting window;继续调用mSupervisor.resumeFocusedStackTopActivityLocked)显示栈顶元素(参考自:https://blog.csdn.net/shulianghan/article/details/120249208)

  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

  1. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

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

  2. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

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

  3. ActivityStack.resumeTopActivityUncheckedLocked

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

  4. 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,这一次调用到resumeTopActivityInnerLocked的时候,会调用到mStackSupervisor.startSpecificActivityLocked(next, true, true)。也就是这个过程中,此时resumeTopActivityInnerLocked已经调用了两次了.

  5. 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

  6. 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。

  7. 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

  8. 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

  9. 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

  10. 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

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启动,所以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);
                    }
                }    
                ......
                if (entryPoint == null) entryPoint = "android.app.ActivityThread";
                ......
                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中完成,zygoteServer.runSelectLoop启动一个死循环,就是为了fork进程,这里会取出ams发送来的参数,fork一个子进程,此处即app进程。
    如果是子进程,会执行caller.run()。原因后续分析。

  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()标记为子进程,即把当前进程的mIsForkChild设置为true;由Zygote进程创建的子进程会继承Zygote进程中创建的Socket文件描述符,而这里的子进程又不会用到它,因此,这里就调用closeServerSocket方法来关闭它,再通过ZygoteConnection.handleChildProc返回一个Runnable,因为mIsForkChild为true,这样新的子进程就跳出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. ZygoteConnection.handleChildProc

    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) {
            ......
            RuntimeInit.commonInit();
            ZygoteInit.nativeZygoteInit();
            return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
        }
    

调用zygoteInitNative方法来执行一个Binder进程间通信机制的初始化工作:打开Binder驱动,mmap映射,启动Binder线程池(此时启动一个Binder主线程)。这个过程参考进程的Binder线程池工作过程
String[] argv里面就是ActivityThread.main相关信息,将这些信息参数封装进一个Runnable里。

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

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

  2. 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中调用.

  3. 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("<pre-initialized>");
            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();。

  4. 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

  5. ActivityManagerService.attachApplication

    @Override
        public final void attachApplication(IApplicationThread thread) {
            synchronized (this) {
                ......
                attachApplicationLocked(thread, callingPid);
                ......
            }
        }
    
  6. 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

  7. 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

  8. 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;通过LoadedApk.makeApplication创建Application对象,然后回调Application的onCreate,注意:Application的attachBaseContext方法在makeAppliaction就调用了.

  9. 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创建.

  10. Instrumentation.newApplication

    static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }
    
  11. 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)

  12. 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

  13. 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

  14. 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 {
            ......
        }
    }
    
  15. 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

  16. 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才真正可见并且可交互。

  17. Activity.makeVisible

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



PS:感谢老罗的Android之旅

Android应用程序启动过程源代码分析
Android系统进程Zygote启动过程的源代码分析

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值