Android10 App 启动分析进程创建源码解析

目录
  • 正文
  • RootActivityContainer
  • ActivityStartController
    • 调用startActivityUnchecked方法
  • ActivityStackSupervisor
  • 启动进程
    • RuntimeInit.applicationInit这个方法

正文

从前文# Android 10 启动分析之SystemServer篇 (四)中可以得知,系统在完成所有的初始化工作后,会通过

mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");

这条语句,来启动android系统的第一个App,即Launcher应用。这篇文章,我们便以Launcher为引子来探讨一下App的启动流程,在启动App时,系统究竟做了哪些操作?

AMS调用startHomeOnAllDisplays方法后,经过层层追溯,我们最终将目光定位到RootActivityContainer中的startHomeOnDisplay方法。

RootActivityContainer

RootActivityContainer源码路径为 /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java,其相关代码如下:

boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
         boolean fromHomeKey) {
     // 如果displayId无效,则退回到顶层拥有焦点的显示设备
     if (displayId == INVALID_DISPLAY) {
         displayId = getTopDisplayFocusedStack().mDisplayId;
     }
     Intent homeIntent = null;
     ActivityInfo aInfo = null;
     if (displayId == DEFAULT_DISPLAY) {
         //获取lancher的第一个页面的intent,其category为Intent.CATEGORY_HOME
         homeIntent = mService.getHomeIntent();
         //通过intent找到launcher中AndroidManifest对应的activity标签,解析出相应的ActivityInfo和applicationInfo信息
         aInfo = resolveHomeActivity(userId, homeIntent);
     } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
         //多屏显示功能,具体参考https://source.android.google.cn/devices/tech/display/multi_display/system-decorations#launcher,在此不做分析
         Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
         aInfo = info.first;
         homeIntent = info.second;
     }
     if (aInfo == null || homeIntent == null) {
         return false;
     }
     //在启动前,校验是否满足启动条件,大概校验了 displayId的有效性、对应activity的启动模式、是否处于工厂测试模式等等
     if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
         return false;
     }
     // 更新component信息
     homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
     homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
     // 传入的fromHomeKey的值为false
     if (fromHomeKey) {
         homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
     }
     // Update the reason for ANR debugging to verify if the user activity is the one that
     // actually launched.
     final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
             aInfo.applicationInfo.uid) + ":" + displayId;
       //转到ActivityStartController类中继续调用startHomeActivity方法
     mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
             displayId);
     return true;
 }

我们继续往下追踪:

ActivityStartController

ActivityStartController的源码路径为 /frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

相关代码如下:

  void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
      //这句话只是创建了一个ActivityOptions的对象
        final ActivityOptions options = ActivityOptions.makeBasic();
        //FULLSCREEN模式启动Activity
        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
        if (!ActivityRecord.isResolverActivity(aInfo.name)) {
            // 判断当前是否拥有多个launcher并处于选择launcher状态,否的话设置ACTIVITY_TYPE_HOME属性,直接启动launcher的activity
            options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
        }
        options.setLaunchDisplayId(displayId);
        //执行启动任务
        mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                .setOutActivity(tmpOutRecord)
                .setCallingUid(0)
                .setActivityInfo(aInfo)
                .setActivityOptions(options.toBundle())
                .execute();
        mLastHomeActivityStartRecord = tmpOutRecord[0];
        final ActivityDisplay display =
                mService.mRootActivityContainer.getActivityDisplay(displayId);
        final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
        if (homeStack != null && homeStack.mInResumeTopActivity) {
            // If we are in resume section already, home activity will be initialized, but not
            // resumed (to avoid recursive resume) and will stay that way until something pokes it
            // again. We need to schedule another resume.
            mSupervisor.scheduleResumeTopActivities();
        }
    }

我们从obtainStarter这行代码开始看起,这段代码的执行,意味着开始进入了activity的启动流程。

ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
}

这里mFactory是一个Factory接口,其实现类为DefaultFactory

 public ActivityStarter obtain() {
            ActivityStarter starter = mStarterPool.acquire();
            if (starter == null) {
                starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
            }
            return starter;
        }

调用obtain方法时,会首先尝试从缓存池中获取一个ActivityStarter对象,如果获取不到,才去新建一个。

我们将目光回转,重新聚焦到execute这个方法上。

 int execute() {
        try {
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                        mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup,
                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
            } else {
                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup,
                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
            }
        } finally {
            onExecutionComplete();
        }
    }

mayWait为false,进入else分支。

  private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            SafeActivityOptions options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
            PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
        ...
        //创建被启动的activity对应的ActivityRecord对象
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, checkedOptions, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;
        }
        final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
        //如果我们启动的activity与当前恢复的activity的uid不同,请检查是否允许应用程序切换。
        if (voiceSession == null && (stack.getResumedActivity() == null
                || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                    realCallingPid, realCallingUid, "Activity start")) {
                if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
                    mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
                            sourceRecord, startFlags, stack, callerApp));
                }
                ActivityOptions.abort(checkedOptions);
                return ActivityManager.START_SWITCHES_CANCELED;
            }
        }
        mService.onStartActivitySetDidAppSwitch();
        mController.doPendingActivityLaunches(false);
        final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
        return res;
    }

在最后,代码会进入如下分支:

   private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity, boolean restrictedBgActivity) {
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try {
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
        } finally {
            final ActivityStack currentStack = r.getActivityStack();
            startedActivityStack = currentStack != null ? currentStack : mTargetStack;
            if (ActivityManager.isStartResultSuccessful(result)) {
                if (startedActivityStack != null) {
                    // If there is no state change (e.g. a resumed activity is reparented to
                    // top of another display) to trigger a visibility/configuration checking,
                    // we have to update the configuration for changing to different display.
                    final ActivityRecord currentTop =
                            startedActivityStack.topRunningActivityLocked();
                    if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
                        mRootActivityContainer.ensureVisibilityAndConfig(
                                currentTop, currentTop.getDisplayId(),
                                true /* markFrozenIfConfigChanged */, false /* deferResume */);
                    }
                }
            } else {
                // If we are not able to proceed, disassociate the activity from the task.
                // Leaving an activity in an incomplete state can lead to issues, such as
                // performing operations without a window container.
                final ActivityStack stack = mStartActivity.getActivityStack();
                if (stack != null) {
                    stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                            null /* intentResultData */, "startActivity", true /* oomAdj */);
                }
                // Stack should also be detached from display and be removed if it's empty.
                if (startedActivityStack != null && startedActivityStack.isAttached()
                        && startedActivityStack.numActivities() == 0
                        && !startedActivityStack.isActivityTypeHome()) {
                    startedActivityStack.remove();
                }
            }
            mService.mWindowManager.continueSurfaceLayout();
        }
        postStartActivityProcessing(r, result, startedActivityStack);
        return result;
    }

调用startActivityUnchecked方法

其中,调用了startActivityUnchecked方法。

 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
      ...
        //如果正在启动的activity与当前在顶部的activity相同,那么我们需要检查它是否应该只启动一次
        final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
        final ActivityRecord topFocused = topStack.getTopActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
                && top.mUserId == mStartActivity.mUserId
                && top.attachedToProcess()
                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
                // This allows home activity to automatically launch on secondary display when
                // display added, if home was the top activity on default display, instead of
                // sending new intent to the home activity on default display.
                && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
        if (dontStart) {
            // For paranoia, make sure we have correctly resumed the top activity.
            topStack.mLastPausedActivity = null;
            if (mDoResume) {
                mRootActivityContainer.resumeFocusedStacksTopActivities();
            }
            ActivityOptions.abort(mOptions);
            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
                // We don't need to start a new activity, and the client said not to do
                // anything if that is the case, so this is it!
                return START_RETURN_INTENT_TO_CALLER;
            }
            deliverNewIntent(top);
            // Don't use mStartActivity.task to show the toast. We're not starting a new activity
            // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
            mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
                    mPreferredDisplayId, topStack);
            return START_DELIVERED_TO_TOP;
        }
        ...
        //往ActivityStack中写入启动的activity记录,同时更新TaskRecord信息
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTaskRecord().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                //如果activity无焦点的,我们不能恢复它,但仍然希望确保它在启动时时变得可见(这也将触发入场动画)。此外,我们不希望在当前有覆盖层的Task中恢复activity,因为正在启动的activity只需要处于可见的暂停状态,直到覆盖层被移除。
                mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
                // Go ahead and tell window manager to execute app transition for this activity
                // since the app transition will not be triggered through the resume channel.
                mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
            } else {
                // If the target stack was not previously focusable (previous top running activity
                // on that stack was not visible) then any prior calls to move the stack to the
                // will not update the focused stack.  If starting the new activity now allows the
                // task stack to be focusable, then ensure that we now update the focused stack
                // accordingly.
                if (mTargetStack.isFocusable()
                        && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                mRootActivityContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
            }
        } else if (mStartActivity != null) {
            mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
        }
        mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
                preferredWindowingMode, mPreferredDisplayId, mTargetStack);
        return START_SUCCESS;
    }

我们关注一下这行代码,

 mRootActivityContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);

它调用了RootActivityContainerresumeFocusedStacksTopActivities方法,启动目标ActivityStack的最顶层activity。

我们接着往下追踪,它调用了 ActivityStackresumeTopActivityInnerLocked方法。

 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
       ...
        //暂停上一个activity
        boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
       ...
  // 如果最近的activity没有历史记录,但由于设备进入睡眠状态而被停止,而不是停止+销毁,我们需要确保销毁它,因为我们正在使一个新的activity处于最顶层。
        if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
                !mLastNoHistoryActivity.finishing) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "no-history finish of " + mLastNoHistoryActivity + " on new resume");
            requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                    null, "resume-no-history", false);
            mLastNoHistoryActivity = null;
        }
        if (prev != null && prev != next && next.nowVisible) {
            /*下一个activity已经可见,所以现在隐藏前一个activity的窗口,以便我们可以尽快显示新的activity。
            我们只有在前一个结束时才这样做,这意味着它在resume的那个之上,所以快速隐藏它是有好处的。
            否则,我们希望按照正常的方式显示resume的activity,
            这样我们就可以根据新activity是否全屏来决定是否应该隐藏以前的activity。*/
            if (prev.finishing) {
                prev.setVisibility(false);
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                        "Not waiting for visible to hide: " + prev
                        + ", nowVisible=" + next.nowVisible);
            } else {
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                        "Previous already visible but still waiting to hide: " + prev
                        + ", nowVisible=" + next.nowVisible);
            }
        }
        // Launching this app's activity, make sure the app is no longer
        // considered stopped.
        try {
            AppGlobals.getPackageManager().setPackageStoppedState(
                    next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */
        } catch (RemoteException e1) {
        } catch (IllegalArgumentException e) {
            Slog.w(TAG, "Failed trying to unstop package "
                    + next.packageName + ": " + e);
        }
        // 我们正在启动下一个activity,所以告诉window manager,上一个activity很快就会被隐藏。这样,它可以知道在计算所需的屏幕方向时忽略它。
        boolean anim = true;
        final DisplayContent dc = getDisplay().mDisplayContent;
        if (prev != null) {
            if (prev.finishing) {
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare close transition: prev=" + prev);
                if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
                    anim = false;
                    dc.prepareAppTransition(TRANSIT_NONE, false);
                } else {
                    dc.prepareAppTransition(
                            prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_CLOSE
                                    : TRANSIT_TASK_CLOSE, false);
                }
                prev.setVisibility(false);
            } else {
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare open transition: prev=" + prev);
                if (mStackSupervisor.mNoAnimActivities.contains(next)) {
                    anim = false;
                    dc.prepareAppTransition(TRANSIT_NONE, false);
                } else {
                    dc.prepareAppTransition(
                            prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_OPEN
                                    : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND
                                            : TRANSIT_TASK_OPEN, false);
                }
            }
        } else {
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
            if (mStackSupervisor.mNoAnimActivities.contains(next)) {
                anim = false;
                dc.prepareAppTransition(TRANSIT_NONE, false);
            } else {
                dc.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
            }
        }
        if (anim) {
            next.applyOptionsLocked();
        } else {
            next.clearOptionsLocked();
        }
        mStackSupervisor.mNoAnimActivities.clear();
        if (next.attachedToProcess()) {
            ...
            //只有启动过的activity才会进入此分支
        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    //冷启动的过渡页,在这里会载入manifest配置的主题背景,如果没有的话,默认白屏或黑屏
                    next.showStartingWindow(null /* prev */, false /* newTask */,
                            false /* taskSwich */);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        return true;
    }

通过源码,我们可以得知:先对上一个Activity执行pause操作,再启动目标activity,最终进入到了ActivityStackSupervior.startSpecificActivityLocked方法中。在启动Activity之前,调用了next.showStartingWindow方法来展示一个window,这就是冷启动时出现白屏的原因。

我们继续往下追踪:

ActivityStackSupervisor

ActivityStackSupervisor的源码路径为 /frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

 void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);
        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                realStartActivityLocked(r, wpc, 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.
            knownToBeDead = true;
        }
        // Suppress transition until the new activity becomes ready, otherwise the keyguard can
        // appear for a short amount of time before the new process with the new activity had the
        // ability to set its showWhenLocked flags.
        if (getKeyguardController().isKeyguardLocked()) {
            r.notifyUnknownVisibilityLaunched();
        }
        try {
            if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                        + r.processName);
            }
            //发布消息以启动进程,从而避免在ATMS锁被持有的情况下调用AMS时可能出现的死锁
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);
        } finally {
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

上面这段方法里有个很重要的判断,if(wpc != null && wpc.hasThread()),通过进程名和application uid 获取的WindowProcessController对象进行校验,判断要启动的activity进程是否已启动。显然,app第一次启动时,进程还不存在,首先先得创建应用进程。

final Message msg = PooledLambda.obtainMessage(
                 ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                 r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
         mService.mH.sendMessage(msg);

这里通过Handler,发送了一条Message,以避免在ATMS锁被持有的情况下调用AMS时可能出现的死锁。这条Message实际调用的是ActivityManagerServicestartProcess方法。

启动进程

ActivityManagerService的源码位置为 /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

startProcess实际调用的是startProcessLocked方法,我们直接从它看起。

final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }

这里调用的是 ProcessList类里的startProcessLocked的方法,我们继续往下看。

  final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        ...
        ProcessRecord app;
        // 以下三种情况,我们不需要做任何额外的处理
        // (1) 存在一个application 记录
        // (2) 调用者认为它仍然存活,或者没有线程对象连接到它,所以我们知道它没有crash
        // (3) 有一个pid分配给它,所以它要么正在启动,要么已经运行
        if (app != null && app.pid > 0) {
            if ((!knownToBeDead && !app.killed) || app.thread == null) {
                // 我们已经有应用程序在运行,或者正在等待它出现(我们有一个pid,但还没有它的线程),所以保持它
                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
                // If this is a new package in the process, add the package to the list
                app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
                checkSlow(startTime, "startProcess: done, added package to proc");
                return app;
            }
            // An application record is attached to a previous process,
            // clean it up now.
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
            checkSlow(startTime, "startProcess: bad proc running, killing");
            ProcessList.killProcessGroup(app.uid, app.pid);
            mService.handleAppDiedLocked(app, true, true);
            checkSlow(startTime, "startProcess: done killing old proc");
        }
        if (app == null) {
            checkSlow(startTime, "startProcess: creating new process record");
            //创建一条ProcessRecord
            app = new ProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
            if (app == null) {
                Slog.w(TAG, "Failed making new process record for "
                        + processName + "/" + info.uid + " isolated=" + isolated);
                return null;
            }
            app.crashHandler = crashHandler;
            app.isolatedEntryPoint = entryPoint;
            app.isolatedEntryPointArgs = entryPointArgs;
            checkSlow(startTime, "startProcess: done creating new process record");
        } else {
            // If this is a new package in the process, add the package to the list
            app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
            checkSlow(startTime, "startProcess: added package to existing proc");
        }
        // If the system is not ready yet, then hold off on starting this
        // process until it is.
        if (!mService.mProcessesReady
                && !mService.isAllowedWhileBooting(info)
                && !allowWhileBooting) {
            if (!mService.mProcessesOnHold.contains(app)) {
                mService.mProcessesOnHold.add(app);
            }
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
                    "System not ready, putting on hold: " + app);
            checkSlow(startTime, "startProcess: returning with proc on hold");
            return app;
        }
        checkSlow(startTime, "startProcess: stepping in to startProcess");
        final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
        checkSlow(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }

可以看到,在启动一个新的进程时,有两个比较重要的步骤。一是通过newProcessRecordLocked方法首先创建一条进程记录,然后再通过startProcessLocked方法去创建一个进程。

 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            boolean disableHiddenApiChecks, boolean mountExtStorageFull,
            String abiOverride) {
            int uid = app.uid;
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if (!app.isolated) {
               ...
            final String entryPoint = "android.app.ActivityThread";
            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                    startTime);
        } catch (RuntimeException e) {
            Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
            mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                    false, false, true, false, false, app.userId, "start failure");
            return false;
        }
    }

这里请注意一下entryPoint这个变量的值————android.app.ActivityThread,它会经过一段漫长的调用链,最终在RuntimeInit这个类中发挥它的作用。

boolean startProcessLocked(HostingRecord hostingRecord,
            String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        app.pendingStart = true;
        app.killedByAm = false;
        app.removed = false;
        app.killed = false;
       ...
        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
        app.setStartParams(uid, hostingRecord, seInfo, startTime);
        app.setUsingWrapper(invokeWith != null
                || SystemProperties.get("wrap." + app.processName) != null);
        mPendingStarts.put(startSeq, app);
        if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
        //默认以异步方式启动
            mService.mProcStartHandler.post(() -> {
                try {
                    final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
                            entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
                            app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
                    synchronized (mService) {
                        handleProcessStartedLocked(app, startResult, startSeq);
                    }
                } catch (RuntimeException e) {
                    synchronized (mService) {
                        Slog.e(ActivityManagerService.TAG, "Failure starting process "
                                + app.processName, e);
                        mPendingStarts.remove(startSeq);
                        app.pendingStart = false;
                        mService.forceStopPackageLocked(app.info.packageName,
                                UserHandle.getAppId(app.uid),
                                false, false, true, false, false, app.userId, "start failure");
                    }
                }
            });
            return true;
        } else {
            try {
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
                        invokeWith, startTime);
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
            } catch (RuntimeException e) {
                Slog.e(ActivityManagerService.TAG, "Failure starting process "
                        + app.processName, e);
                app.pendingStart = false;
                mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                        false, false, true, false, false, app.userId, "start failure");
            }
            return app.pid > 0;
        }
    }

继续看startProcess方法:

private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        try {
            final Process.ProcessStartResult startResult;
            //hostingRecord初始化参数为null,并未指定mHostingZygote属性,因此会进入最后一个分支
            if (hostingRecord.usesWebviewZygote()) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else if (hostingRecord.usesAppZygote()) {
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
                startResult = appZygote.getProcess().start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*useUsapPool=*/ false,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            }
            checkSlow(startTime, "startProcess: returned from zygote!");
            return startResult;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

Process的源码位置为 frameworks/base/core/java/android/os/Process.java

 public static ProcessStartResult start(@NonNull final String processClass,
                                           @Nullable final String niceName,
                                           int uid, int gid, @Nullable int[] gids,
                                           int runtimeFlags,
                                           int mountExternal,
                                           int targetSdkVersion,
                                           @Nullable String seInfo,
                                           @NonNull String abi,
                                           @Nullable String instructionSet,
                                           @Nullable String appDataDir,
                                           @Nullable String invokeWith,
                                           @Nullable String packageName,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    /*useUsapPool=*/ true, zygoteArgs);
    }

其中ZYGOTE_PROCESS是一个ZygoteProcess对象,它实际调用的是ZygoteProcess里的start方法。

public final Process.ProcessStartResult start(@NonNull final String processClass,
                                                  final String niceName,
                                                  int uid, int gid, @Nullable int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  @Nullable String seInfo,
                                                  @NonNull String abi,
                                                  @Nullable String instructionSet,
                                                  @Nullable String appDataDir,
                                                  @Nullable String invokeWith,
                                                  @Nullable String packageName,
                                                  boolean useUsapPool,
                                                  @Nullable String[] zygoteArgs) {
        // TODO (chriswailes): Is there a better place to check this value?
        if (fetchUsapPoolEnabledPropWithMinInterval()) {
            informZygotesOfUsapPoolStatus();
        }
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, useUsapPool, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }
 private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                      @Nullable final String niceName,
                                                      final int uid, final int gid,
                                                      @Nullable final int[] gids,
                                                      int runtimeFlags, int mountExternal,
                                                      int targetSdkVersion,
                                                      @Nullable String seInfo,
                                                      @NonNull String abi,
                                                      @Nullable String instructionSet,
                                                      @Nullable String appDataDir,
                                                      @Nullable String invokeWith,
                                                      boolean startChildZygote,
                                                      @Nullable String packageName,
                                                      boolean useUsapPool,
                                                      @Nullable String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
        ArrayList<String> argsForZygote = new ArrayList<>();
        // --runtime-args, --setuid=, --setgid=,
        // and --setgroups= must go first
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        argsForZygote.add("--runtime-flags=" + runtimeFlags);
        if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
            argsForZygote.add("--mount-external-default");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
            argsForZygote.add("--mount-external-read");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
            argsForZygote.add("--mount-external-write");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
            argsForZygote.add("--mount-external-full");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
            argsForZygote.add("--mount-external-installer");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
            argsForZygote.add("--mount-external-legacy");
        }
        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
        // --setgroups is a comma-separated list
        if (gids != null && gids.length > 0) {
            StringBuilder sb = new StringBuilder();
            sb.append("--setgroups=");
            int sz = gids.length;
            for (int i = 0; i < sz; i++) {
                if (i != 0) {
                    sb.append(',');
                }
                sb.append(gids[i]);
            }
            argsForZygote.add(sb.toString());
        }
        if (niceName != null) {
            argsForZygote.add("--nice-name=" + niceName);
        }
        if (seInfo != null) {
            argsForZygote.add("--seinfo=" + seInfo);
        }
        if (instructionSet != null) {
            argsForZygote.add("--instruction-set=" + instructionSet);
        }
        if (appDataDir != null) {
            argsForZygote.add("--app-data-dir=" + appDataDir);
        }
        if (invokeWith != null) {
            argsForZygote.add("--invoke-with");
            argsForZygote.add(invokeWith);
        }
        if (startChildZygote) {
            argsForZygote.add("--start-child-zygote");
        }
        if (packageName != null) {
            argsForZygote.add("--package-name=" + packageName);
        }
        argsForZygote.add(processClass);
        if (extraArgs != null) {
            Collections.addAll(argsForZygote, extraArgs);
        }
        synchronized(mLock) {
            // The USAP pool can not be used if the application will not use the systems graphics
            // driver.  If that driver is requested use the Zygote application start path.
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              useUsapPool,
                                              argsForZygote);
        }
    }

值得注意的是上面这段代码的openZygoteSocketIfNeeded这个方法,它采用socket通信方式,尝试连接路径为/dev/socket/、名称为zygote的服务端。

zygoteSendArgsAndGetResult方法里实际调用了attemptZygoteSendArgsAndGetResult方法,内容如下:

 private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
        try {
            final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
            final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
            zygoteWriter.write(msgStr);
            zygoteWriter.flush();
            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            Process.ProcessStartResult result = new Process.ProcessStartResult();
            result.pid = zygoteInputStream.readInt();
            result.usingWrapper = zygoteInputStream.readBoolean();
            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
            return result;
        } catch (IOException ex) {
            zygoteState.close();
            Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                    + ex.toString());
            throw new ZygoteStartFailedEx(ex);
        }
    }

请注意上述方法的zygoteWriter这个变量,它负责将进程启动参数发送给服务端,由服务端去孵化进程。那么,这个服务端到底是哪个类呢?

答案是ZygoteServer.java,源码路径为 frameworks/base/core/java/com/android/internal/os/ZygoteServer.java.

ZygoteServer会在系统启动的时候,创建一个Socket服务端,用于接收客户端的fork请求。ZygoteServer在初始化结束后,会调用runSelectLoop方法,用于处理客户端的消息。当客户端请求fork进程时,runSelectLoop方法会转交给ZygoteConnection类的processOneCommand方法去处理。

(ps : 如需了解更多关于Zegote的信息,请参考文章 Android 10 启动分析之Zygote篇)

 Runnable processOneCommand(ZygoteServer zygoteServer) {
        String args[];
        ZygoteArguments parsedArgs = null;
        FileDescriptor[] descriptors;
       ...
        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
        try {
            if (pid == 0) {
                // in child
                zygoteServer.setForkChild();
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                return handleChildProc(parsedArgs, descriptors, childPipeFd,
                        parsedArgs.mStartChildZygote);
            } 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);
        }
    }
 public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
            int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
            int targetSdkVersion) {
        ZygoteHooks.preFork();
        // Resets nice priority for zygote process.
        resetNicePriority();
        int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir);
        // Enable tracing as soon as possible for the child process.
        if (pid == 0) {
            Zygote.disableExecuteOnly(targetSdkVersion);
            Trace.setTracingEnabled(true, runtimeFlags);
            // Note that this event ends at the end of handleChildProc,
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
        }
        ZygoteHooks.postForkCommon();
        return pid;
    }

上述Zygote类在这个过程中主要做了以下几点工作:

  • 调用dalvik中ZygoteHookspreFrok进行预处理,主要是停止4个Daemon子线程,HeapTaskDaemon、ReferenceQueueDaemon、FinalizerDaemon、FinalizerWatchdogDaemon,等待所有的子线程结束,最后完成gc堆的初始化工作。
  • 调用com_android_internal_os_zygote.cpp中的nativeForkAndSpecialize方法,主要工作是通过linux机制fork一个子进程,以及进程的一些资源处理,selinux权限处理,JAVA堆线程的一些处理。
  • 调用ZygoteHookspostForkCommon方法,启动Zygote的4个Daemon线程。

在执行forkAndSpecialize方法后,代码将继续执行ZygoteConnection中的handleChildProc这个方法。

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
           FileDescriptor pipeFd, boolean isZygote) {
      ...
       if (parsedArgs.mInvokeWith != null) {
           WrapperInit.execApplication(parsedArgs.mInvokeWith,
                   parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                   VMRuntime.getCurrentInstructionSet(),
                   pipeFd, parsedArgs.mRemainingArgs);
           // Should not get here.
           throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
       } else {
           if (!isZygote) {
           //进入此分支
               return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                       parsedArgs.mRemainingArgs, null /* classLoader */);
           } else {
               return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                       parsedArgs.mRemainingArgs, null /* classLoader */);
           }
       }
   }
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
         ...
         //初始化运行环境
        RuntimeInit.commonInit();
        //启动binder线程池
        ZygoteInit.nativeZygoteInit();
        //程序入口函数
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

RuntimeInit.applicationInit这个方法

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);
        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
        final Arguments args = new Arguments(argv);
        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        // Remaining arguments are passed to the start class's static main
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }
 protected 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);
    }

这里通过反射获得了className变量中的main方法,并传递给MethodAndArgsCaller用于构造一个Runnable。只要执行此Runnable,就会开始执行className变量中的main方法。

className变量的值究竟是什么呢?

还记得我们前文重点强调的entryPoint这个变量吗?不记得的读者请自行返回再查看一下。android.app.ActivityThread就是我们要执行的目标类。

ActivityThread类main方法的调用,标识着 应用已全部完成进程的创建和初始化过程,下面将进入ApplicationActivity的创建与启动流程。下一篇文章,我们再来继续探讨剩下的内容。

最后,让我们用图表对上述流程做一个总结归纳:

[ActivityManagerService.java]
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
   |
[RootActivityContainer.java]
startHomeOnDisplay()		     //获取lancher的第一个页面的intent,其category为Intent.CATEGORY_HOME
   |
[ActivityStartController.java]
startHomeActivity()
   |
[ActivityStarter.java]
execute()			     //开始进入activity启动流程
startActivity()
startActivityUnchecked()
   |
[RootActivityContainer.java]
resumeFocusedStacksTopActivities()   //启动目标ActivityStack的最顶层activity
   |
[ActivityStack.java]
resumeTopActivityInnerLocked()      //暂停上一个activity,载入manifest的主题背景
   |
[ActivityStackSupervisor.java]
startSpecificActivityLocked()       //检查进程是否已启动,通过handler消息机制启动新的进程
   |
[ActivityManagerService.java]
startProcessLocked()
   |
[ProcessList.java]
startProcessLocked()               //指定了进程创建成功后程序启动入口类为android.app.ActivityThread
startProcess()
   |
[Process.java]
start()
   |
[ZygoteProcess.java]
start()
startViaZygote()		   //初始化Zygote的启动参数,连接ZygoteServer服务端
attemptZygoteSendArgsAndGetResult()
   |
[ZygoteServer.java]
processOneCommand()
   |		|
   |  [Zygote.java]
   |  forkAndSpecialize()
   |        |
   |  [ZygoteHooks.java]
   |	  preFrok()		   //停止4个子线程,等待所有的子线程结束,最后完成gc堆的初始化工作
   |		|
   |  [com_android_internal_os_zygote.cpp]
   |  nativeForkAndSpecialize()       //fork子进程
   |        |
   |  [ZygoteHooks.java]
   |  postForkCommon()                //启动Zygote的4个Daemon线程
   |
[ZygoteConnection.java]
handleChildProc()
   |
[ZygoteInit.java]
zygoteInit()				//初始化运行环境、启动binder线程池
   |
[RuntimeInit.java]
applicationInit()
   |
[ActivityThread.java]
main()

以上就是Android10 App 启动分析进程创建源码解析的详细内容,更多关于Android10 App启动进程创建的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android 10 启动之servicemanager源码解析

    目录 正文 获取服务 注册服务 正文 上一篇文章: Android 10 启动分析之Init篇 (一) 在前文提到,init进程会在在Trigger 为init的Action中,启动servicemanager服务,这篇文章我们就来具体分析一下servicemanager服务,它到底做了哪些事情. servicemanager服务的源码位于/frameworks/native/cmds/servicemanager/service_manager.c,我们将从这个类的入口开始看起. int ma

  • Android10 App启动Activity源码分析

    目录 正文 ActivityThread的main方法 Application Context对象 LaunchActivityItem ClientLifecycleManager ClientTransaction TransactionExecutor executeLifecycleState方法 正文 上一篇: Android 10 App启动分析之进程创建篇(一) 上一篇文章,我们探讨了App启动过程中进程创建及初始化的流程,这篇文章我们接着上篇的内容,继续探讨App的Applica

  • Android10 启动之SystemServer源码分析

    目录 正文 createSystemContext startBootstrapServices startCoreServices startOtherServices 正文 上一篇文章: # Android 10 启动分析之Zygote篇 (三) 紧接着上一篇文章的内容,我们从这篇文章开始来分析一下 SystemServer. system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService.PowerManagerService

  • Android 10 启动Init进程解析

    目录 按下电源键时,android做了啥? init进程解析 FirstStageMain SetupSelinux SecondStageMain init.rc 解析 按下电源键时,android做了啥? 当我们按下电源键时,手机开始上电,并从地址0x00000000处开始执行,而这个地址通常是Bootloader程序的首地址. bootloader是一段裸机程序,是直接与硬件打交道的,其最终目的是“初始化并检测硬件设备,准备好软件环境,最后调用操作系统内核”.除此之外,bootloader

  • Android10 客户端事务管理ClientLifecycleManager源码解析

    目录 正文 ClientLifecycleManager ClientTransaction TransactionExecutor executeLifecycleState 正文 在Android 10 App启动分析之Activity启动篇(二)一文中,简单地介绍了Activity的生命周期管理器是如何调度Activity进入onCreate生命周期的流程.这篇文章,我们将详细地分析framework中activity的生命周期管理功能,从更宏观的角度来更全面地了解生命周期及相关事务的工作

  • Android10 启动Zygote源码解析

    目录 app_main ZygoteInit preload preloadClasses preloadResources preloadSharedLibraries forkSystemServer app_main 上一篇文章: # Android 10 启动分析之servicemanager篇 (二) 在init篇中有提到,init进程会在在Trigger 为late-init的Action中,启动Zygote服务,这篇文章我们就来具体分析一下Zygote服务,去挖掘一下Zygote负

  • Android10 App 启动分析进程创建源码解析

    目录 正文 RootActivityContainer ActivityStartController 调用startActivityUnchecked方法 ActivityStackSupervisor 启动进程 RuntimeInit.applicationInit这个方法 正文 从前文# Android 10 启动分析之SystemServer篇 (四)中可以得知,系统在完成所有的初始化工作后,会通过 mAtmInternal.startHomeOnAllDisplays(currentU

  • Netty分布式server启动流程Nio创建源码分析

    目录 NioServerSocketChannel创建 继承关系 绑定端口 端口封装成socket地址对象 跟进initAndRegister()方法 创建channel 父类的构造方法 将jdk的channel设置为非阻塞模式 前文传送门 Netty分布式Server启动流程服务端初始化源码分析 NioServerSocketChannel创建 我们如果熟悉Nio, 则对channel的概念则不会陌生, channel在相当于一个通道, 用于数据的传输 Netty将jdk的channel进行了

  • Netty启动流程注册多路复用源码解析

    目录 注册多路复用 注册channel的步骤 首先看下config()方法 回到initAndRegister()方法: 跟到MultithreadEventLoopGroup的register()方法: 回顾下第二小节channel初始化的步骤: 我们继续看看register()方法: 我们重点关注register0(promise), 跟进去: 我们重点关注doRegister()这个方法 前文传送门:Netty启动流程服务端channel初始化 注册多路复用 回到上一小节的代码: fina

  • 分析Android Choreographer源码

    一.前言 目前大部分手机都是 60Hz 的刷新率,也就是 16.6ms 刷新一次,系统为了配合屏幕的刷新频率,将 Vsync 的周期也设置为 16.6 ms,每个 16.6 ms , Vsync 信号唤醒 Choreographer 来做 App 的绘制操作,这就是引入 Choreographer 的主要作用.了解 Choreographer 还可以帮助 App 开发者知道程序每一帧运行的基本原理,也可以加深对 Message.Handler.Looper.MessageQueue.Measur

  • SPRING BOOT启动命令参数及源码详析

    前言 使用过Spring Boot,我们都知道通过java -jar可以快速启动Spring Boot项目.同时,也可以通过在执行jar -jar时传递参数来进行配置.本文带大家系统的了解一下Spring Boot命令行参数相关的功能及相关源码分析. 命令行参数使用 启动Spring Boot项目时,我们可以通过如下方式传递参数: java -jar xxx.jar --server.port=8081 默认情况下Spring Boot使用8080端口,通过上述参数将其修改为8081端口,而且通

  • RocketMQ源码解析topic创建机制详解

    目录 1. RocketMQ Topic创建机制 2. 自动Topic 3. 手动创建--预先创建 通过界面控制台创建 1. RocketMQ Topic创建机制 以下源码基于Rocket MQ 4.7.0 RocketMQ Topic创建机制分为两种:一种自动创建,一种手动创建.可以通过设置broker的配置文件来禁用或者允许自动创建.默认是开启的允许自动创建 autoCreateTopicEnable=true/false 下面会结合源码来深度分析一下自动创建和手动创建的过程. 2. 自动T

  • Vite的createServer启动源码解析

    目录 启动Vite的createServer 通过vite3安装一个vue的工程 添加断点并开启调试 边调试边理解代码 启动Vite的createServer 为了能够了解vite里面运行了什么,通过执行单步调试能够更加直观的知道Vite具体内容.所以这次我们来试着启动Vite的createServer,并进行调试. 通过vite3安装一个vue的工程 进入工作目录,运行下面的代码,项目名称随意,语言用Vue. npm create vite 进入工程目录安装依赖 添加断点并开启调试 通过vsc

随机推荐