【Android-AMS】startActivity分析(之一)

Activity的管理(几个重要文件的组织关系)

AMS中的Activity主要通过以下几个类来管理:

ActivityManagerService.java

ActivityStackSupervisor.java 、其内部类ActivityDisplay

ActivityStack.java

TaskRecord.java

ActivityRecord.java

下面通过几段代码来展示它们之间的组织关系:

  • a)【ActivityManagerService.java】:AMS包含一个ActivityStackSupervisor成员变量mStackSupervisor:
final ActivityStackSupervisor mStackSupervisor;
  • b)【ActivityStackSupervisor.java::ActivityDisplay】:ActivityStackSupervisor包含一个ActivityDisplay数组mActivityDisplays,后者是前者内部类,ActivityDisplay中的一个ActivityStack数组mStacks:
private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>();
    
class ActivityDisplay extends ConfigurationContainer {
        /** Actual Display this object tracks. */
        int mDisplayId;
        Display mDisplay;

        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
        final ArrayList<ActivityStack> mStacks = new ArrayList<>();
    ……
}
  • c)【ActivityStack.java】ActivityStack包含一个TaskRecord数组mTaskHistory
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
  • d)【TaskRecord.java】TaskRecord包含一个ActivityRecord数组mActivityies
final ArrayList<ActivityRecord> mActivities;

由上可知:

重要类的组织关系

ActivityManagerService {
    ActivityStackSupervisor{
        ActivityDisplay[]{
            ActivityStack[] {
                TaskRecord[] {
                    ActivityRecord
}}}}}

我们还可以通过下面的函数来进一步确认这一点:

  • a)【ActivityStackSupervisor.java::findActivityLocked】
    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info,
                                      boolean compareIntentFilters) {
        //遍历所有ActivityDisplay来查找合适的ActivityStack
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            //遍历每一个ActivityStack并调用其findActivityLocked
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityRecord ar = stacks.get(stackNdx)
                        .findActivityLocked(intent, info, compareIntentFilters);
                if (ar != null) {
                    return ar;
                }
            }
        }
        return null;
    }
  • b)【ActivityStack.java::findActivityLocked】
ActivityRecord findActivityLocked(Intent intent, ActivityInfo info,
                                      boolean compareIntentFilters) {
        ComponentName cls = intent.getComponent();
        if (info.targetActivity != null) {
            cls = new ComponentName(info.packageName, info.targetActivity);
        }
        final int userId = UserHandle.getUserId(info.applicationInfo.uid);
        //遍历mTaskHistory查找合适的TaskRecord
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            final TaskRecord task = mTaskHistory.get(taskNdx);
            final ArrayList<ActivityRecord> activities = task.mActivities;
            //遍历每一个TaskRecord查找合适的ActivityRecord
            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                ActivityRecord r = activities.get(activityNdx);
                if (!r.okToShowLocked()) {
                    continue;
                }
                if (!r.finishing && r.userId == userId) {
                    if (compareIntentFilters) {
                        if (r.intent.filterEquals(intent)) {
                            return r;
                        }
                    } else {
                        if (r.intent.getComponent().equals(cls)) {
                            return r;
                        }
                    }
                }
            }
        }
        return null;
    }

由以上分析可知,AMS是通过ActivitySupervisor.java的内部类ActivityDisplay来实现多组显示的:根据不同的mDisplayId来划分不同的ActivityStack。而每一个ActivityStack代表什么呢?我们跟踪一下ActivitySupervisor.java: mActivityDisplays这个成员变量的操作便知一二:

【ActivitySupervisor.java::setWindowManager】

    void setWindowManager(WindowManagerService wm) {
        synchronized (mService) {
            mWindowManager = wm;
            mKeyguardController.setWindowManager(wm);

            mDisplayManager =
                    (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
            mDisplayManager.registerDisplayListener(this, null);
            mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
            //获取DisplayManager所有的Display
            Display[] displays = mDisplayManager.getDisplays();
            for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
                final int displayId = displays[displayNdx].getDisplayId();
                //为第一个Display创建一个ActivityDisplay
                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
                if (activityDisplay.mDisplay == null) {
                    throw new IllegalStateException("Default Display does not exist");
                }
                //将ActivityDisplay放入到mActivityDisplays中
                mActivityDisplays.put(displayId, activityDisplay);
                calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
            }

            mHomeStack = mFocusedStack = mLastFocusedStack =
                    getStack(HOME_STACK_ID, CREATE_IF_NEEDED, ON_TOP);

            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
        }
    }

由此可知:

    mActivityDisplays中的每一个成员对应DisplayManager中的一个Display,而Display又代表什么呢?我们把getDisplays展开(注:这部分代码已经超出AMS的范围):

【DisplayManager.java::getDisplays】

    public Display[] getDisplays() {
        //P1:调用另一个getDisplays请注意参数为null
        return getDisplays(null);
    }    
    
    public Display[] getDisplays(String category) {
        //P2:获取DisplayIds
        final int[] displayIds = mGlobal.getDisplayIds();
        synchronized (mLock) {
            try {
                if (category == null) {
                    //P3:本例是起这个分支:
                    //将一组整型数组映射到一个临时变量mTempDisplays中
                    addAllDisplaysLocked(mTempDisplays, displayIds);
                } else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
                    ……
                }
                //P4:将临时变量mTempDisplays转成Display数组返回
                return mTempDisplays.toArray(new Display[mTempDisplays.size()]);
            } finally {
                mTempDisplays.clear();
            }
        }
    }

继续将P2展开:

扫描二维码关注公众号,回复: 8959124 查看本文章

【DisplayManagerService.java::getDisplayIds】

        @Override // Binder call
        public int[] getDisplayIds() {
            final int callingUid = Binder.getCallingUid();
            final long token = Binder.clearCallingIdentity();
            try {
                //P5:调用getDisplayIdsInternal
                return getDisplayIdsInternal(callingUid);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

    private int[] getDisplayIdsInternal(int callingUid) {
        synchronized (mSyncRoot) {
            //根据逻辑显示来创建displayIds数组
            final int count = mLogicalDisplays.size();
            int[] displayIds = new int[count];
            int n = 0;
            for (int i = 0; i < count; i++) {
                //查找每一个逻辑显示的ID
                LogicalDisplay display = mLogicalDisplays.valueAt(i);
                DisplayInfo info = display.getDisplayInfoLocked();
                if (info.hasAccess(callingUid)) {
                    displayIds[n++] = mLogicalDisplays.keyAt(i);
                }
            }
            if (n != count) {
                //将逻辑显示的id数组返回
                displayIds = Arrays.copyOfRange(displayIds, 0, n);
            }
            return displayIds;
        }
    }

现在终于明了了:ActivityStackSupervisor.java::mActivityDisplays中的每一个成员代表一个逻辑显示器。

再看一眼ActivitySupervisor的创建:

【ActivityManagerService.java::ActivityManagerService】

public ActivityManagerService(Context systemContext) {
        ……
        //创建ActivitiSupervisor实例
        mStackSupervisor = createStackSupervisor();
        mStackSupervisor.onConfigurationChanged(mTempConfig);
        mKeyguardController = mStackSupervisor.mKeyguardController;
        
        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
       //把这个实例交给ActivityStarter等其它几个类的实例使用
        mTaskChangeNotificationController =
                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
        mRecentTasks = new RecentTasks(this, mStackSupervisor);
        ……
}

这段代码可以理解为创建了一个Activity总管家,然后把管家的名片分享给了几个好朋友。

此外ActivityStackSupervisor函数保存了一些特殊的ActivityStack、TaskRecord等:

【ActivityStackSupervisor.java】

ActivityStack mHomeStack;
    //当前获得聚焦的activityStack, 接收输入、启动的activity
    ActivityStack mFocusedStack;
    //最后聚焦的activityStack
    private ActivityStack mLastFocusedStack;
    //等待显示的ActivityRecord
    final ArrayList<ActivityRecord> mActivitiesWaitingForVisibleActivity = new ArrayList<>();
    //等待显示的Activity的信息
    private final ArrayList<WaitInfo> mWaitingForActivityVisible = new ArrayList<>();

    //等待结果的Activity
    final ArrayList<WaitResult> mWaitingActivityLaunched = new ArrayList<>();
    //等待停止的ActivityRecord
    final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>();
    //正在结束的ActivityRecord
    final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>();
    //即将进入睡眠的ActivityRecord
    final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
    //多个窗口变化了的ActivityRecord
    final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>();
    //pip=Picture-in-picture, 画中画模式发生了变化,需要通知application的ActivityRecord
    final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>();
    //P1:所有的ActivityStack
    SparseArray<ActivityStack> mStacks = new SparseArray<>();
    ……
}

看到上面的P1处读者可能会有点疑问,前面不是已经有mActivityDisplay来管理多个逻辑显示器的Activity了吗?为什么还有一个包含了所有ActivityStack的mStacks呢?其实是这样的:mStacks包含了所有已经启动的Activity,而mActivityDisplay包含的是正在显示的Activity。当Activity需要显示的时候才会从mActivity搬到mActivityDisplay中,如:

void moveStackToDisplayLocked(int stackId, int displayId, boolean onTop) {
        //获取(如果没有就创建)逻辑显示器句柄
        final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId);
        if (activityDisplay == null) {
            throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown displayId="
                    + displayId);
        }
        //P2:获取合适的ActivityStack
        final ActivityStack stack = mStacks.get(stackId);
        if (stack == null) {
            throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown stackId="
                    + stackId);
        }
        //P3:获取当前的逻辑显示器句柄,然后判断是否为空、是否为前面逻辑显示器
        final ActivityDisplay currentDisplay = stack.getDisplay();
        if (currentDisplay == null) {
            throw new IllegalStateException("moveStackToDisplayLocked: Stack with stack=" + stack
                    + " is not attached to any display.");
        }

        if (currentDisplay.mDisplayId == displayId) {
            throw new IllegalArgumentException("Trying to move stack=" + stack
                    + " to its current displayId=" + displayId);
        }
        //P4:将ActivityStack与逻辑显示器句柄进行关联
        stack.reparent(activityDisplay, onTop);
        // TODO(multi-display): resize stacks properly if moved from split-screen.
    }

小结:

  • ActivityStackSupervisor是管理Activity的大boss
  • AMS支持多个逻辑显示器,每个逻辑显示器对应一个ActivityStack
  • 每个ActivityStack管理多个任务:TaskRecord
  • 每个任务有多个ActivityRecord

Activity的启动

【ActivityManagerService.java::startActivity】

        public int startActivity(IBinder whoThread, String callingPackage,
                Intent intent, String resolvedType, Bundle bOptions) {
            checkCaller();

            int callingUser = UserHandle.getCallingUserId();
            TaskRecord tr;
            IApplicationThread appThread;
            synchronized (ActivityManagerService.this) {
                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
                if (tr == null) {
                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
                }
                appThread = IApplicationThread.Stub.asInterface(whoThread);
                if (appThread == null) {
                    throw new IllegalArgumentException("Bad app thread " + appThread);
                }
            }
            //P1:调用ActivityStarter的startActivityMayWait函数
            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
                    resolvedType, null, null, null, null, 0, 0, null, null,
                    null, bOptions, false, callingUser, tr, "AppTaskImpl");
        }

早期的版本并没有ActivityStarter这个类,新版本增加这个类顾名思义是把启动Activity的活归入这个类中,让代码更加紧凑。

将P1展开:

【ActivityStarter.java::startActivityMayWait】

final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            TaskRecord inTask, String reason) {
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
        //intent中是否指明了组件
        boolean componentSpecified = intent.getComponent() != null;

        // Save a copy in case ephemeral needs it
        final Intent ephemeralIntent = new Intent(intent);
        // Don't modify the client's object!
        //创建一个新的Intent,防止客户传入的Intent被修改
        intent = new Intent(intent);
        //指明的组件是否有效,如果无效则清空,后面将重新查找组件
        if (componentSpecified
                && intent.getData() != null
                && Intent.ACTION_VIEW.equals(intent.getAction())
                && mService.getPackageManagerInternalLocked()
                        .isInstantAppInstallerComponent(intent.getComponent())) {
            // intercept intents targeted directly to the ephemeral installer the
            // ephemeral installer should never be started with a raw URL; instead
            // adjust the intent so it looks like a "normal" instant app launch
            intent.setComponent(null /*component*/);
            componentSpecified = false;
        }
        ……
        //查询满足条件的ActivityInfo,在mSupervisor.resolveIntent内部和PKMS交互
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
        synchronized (mService) {
            //获取调用进程、用户相关信息,并进一步确认ActivityInfo
            final int realCallingPid = Binder.getCallingPid();
            final int realCallingUid = Binder.getCallingUid();
            ……

            if (aInfo != null &&
                    (aInfo.applicationInfo.privateFlags
                            & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                    //进一步确认ActivityInfo
                    }
                }
            }
            //new一个ActivityRecord并启动
            final ActivityRecord[] outRecord = new ActivityRecord[1];
            //P1:核心调用
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);

            Binder.restoreCallingIdentity(origId);
            if (stack.mConfigWillChange) {
                //如果configureation发生变化,则调用AMS的updateUpdateConfigureationLocked进行处理
                mService.updateConfigurationLocked(globalConfig, null, false);
            }

            if (outResult != null) {
                //如果调用者关注调用结果设置了outResult,则把outResult加入到等待Activity启动结果的队列mWaitingActivityLaunched中,并等待结果
                outResult.result = res;
                if (res == ActivityManager.START_SUCCESS) {
                    mSupervisor.mWaitingActivityLaunched.add(outResult);
                    do {
                        try {
                            mService.wait();
                        } catch (InterruptedException e) {
                        }
                    } while (outResult.result != START_TASK_TO_FRONT
                            && !outResult.timeout && outResult.who == null);
                    if (outResult.result == START_TASK_TO_FRONT) {
                        res = START_TASK_TO_FRONT;
                    }
                }
                ……
            }

            mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, outRecord[0]);
            return res;

主要工作:

  • 通过PKMS查找匹配该Intent的ActivityInfo
  • 通过调用者PID、UID待信息进一步确认该ActivityInfo
  • 创建新的ActivityRrecord并启动
  • 核心调用:startActivityLocked下面将展开分析

【ActivityStarter.java::startActivityLocked】


    int startActivityLocked(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,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason) {

        if (TextUtils.isEmpty(reason)) {
            throw new IllegalArgumentException("Need to specify a reason.");
        }
        mLastStartReason = reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord[0] = null;
        //P2:核心调用
        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask);

        if (outActivity != null) {
            // mLastStartActivityRecord[0] is set in the call to startActivity above.
            outActivity[0] = mLastStartActivityRecord[0];
        }

        // Aborted results are treated as successes externally, but we must track them internally.
        return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
    }

参数多,逻辑少,主要是为P2处的函数startActivity套了一层皮,为记录mLastStartReason、mLastStartActivityTimeMs、mLastStartActivityRecord等。因此,继续展开P2:

startActivity函数分析

【ActivityStarter.java::startActivity】分析之一

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,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask) {
        int err = ActivityManager.START_SUCCESS;
        // Pull the optional Ephemeral Installer-only bundle out of the options early.
        final Bundle verificationBundle
                = options != null ? options.popAppVerificationBundle() : null;

        ProcessRecord callerApp = null;
        //如果caller不为空,则需要从AMS中找到它的ProcesRecord
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller
                        + " (pid=" + callingPid + ") when starting: "
                        + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }

        final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;

        if (err == ActivityManager.START_SUCCESS) {
            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
                    + "} from uid " + callingUid);
        }
        //下面两个变量意义很重要。sourceRecord用于描述启动目标Activity的那个Activity,
        //resultRecord用于描述接收启动结果的Activity,即该Activity的onActivityResult
        //将被调用以通知启动结果。
        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
            sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                    "Will send result to " + resultTo + " " + sourceRecord);
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }
        //获取Intent设置的启动标志
        final int launchFlags = intent.getFlags();
        //处理FLAG_ACTIVITY_FORWARD_RESULT场景,例如:有这怎么三个Activity:A、B、C
        //A启动B,B启动C,现在A想直接获取C返回的结果,而B只做一个中转的作用,那么B就可以通过设置
        //FLAG_ACTIVITY_FORWARD_RESULT这个标志来完成。
        if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
            // Transfer the result target from the source activity to the new
            // one being started, including any failures.
            if (requestCode >= 0) {
                ActivityOptions.abort(options);
                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
            }
            resultRecord = sourceRecord.resultTo;
            if (resultRecord != null && !resultRecord.isInStackLocked()) {
                resultRecord = null;
            }
            resultWho = sourceRecord.resultWho;
            requestCode = sourceRecord.requestCode;
            sourceRecord.resultTo = null;
            if (resultRecord != null) {
                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
            }
            if (sourceRecord.launchedFromUid == callingUid) {
                // The new activity is being launched from the same uid as the previous
                // activity in the flow, and asking to forward its result back to the
                // previous.  In this case the activity is serving as a trampoline between
                // the two, so we also want to update its launchedFromPackage to be the
                // same as the previous activity.  Note that this is safe, since we know
                // these two packages come from the same uid; the caller could just as
                // well have supplied that same package name itself.  This specifially
                // deals with the case of an intent picker/chooser being launched in the app
                // flow to redirect to an activity picked by the user, where we want the final
                // activity to consider it to have been launched by the previous app activity.
                callingPackage = sourceRecord.launchedFromPackage;
            }
        }

【ActivityStarter.java::startActivity】分析之二

        //请注意,err这个局部变量的初始值是ActivityManager.START_SUCCESS
        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
            // We couldn't find a class that can handle the given Intent.
            // That's the end of that!
            err = ActivityManager.START_INTENT_NOT_RESOLVED;
        }

        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
            // We couldn't find the specific class specified in the Intent.
            // Also the end of the line.
            err = ActivityManager.START_CLASS_NOT_FOUND;
        }

        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
                && sourceRecord.getTask().voiceSession != null) {
            // If this activity is being launched as part of a voice session, we need
            // to ensure that it is safe to do so.  If the upcoming activity will also
            // be part of the voice session, we can only launch it if it has explicitly
            // said it supports the VOICE category, or it is a part of the calling app.
            if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
                    && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
                try {
                    intent.addCategory(Intent.CATEGORY_VOICE);
                    if (!AppGlobals.getPackageManager().activitySupportsIntent(
                            intent.getComponent(), intent, resolvedType)) {
                        Slog.w(TAG,
                                "Activity being started in current voice task does not support voice: "
                                        + intent);
                        err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
                    }
                } catch (RemoteException e) {
                    Slog.w(TAG, "Failure checking voice capabilities", e);
                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
                }
            }
        }

        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
            // If the caller is starting a new voice session, just make sure the target
            // is actually allowing it to run this way.
            try {
                if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
                        intent, resolvedType)) {
                    Slog.w(TAG,
                            "Activity being started in new voice task does not support: "
                                    + intent);
                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
                }
            } catch (RemoteException e) {
                Slog.w(TAG, "Failure checking voice capabilities", e);
                err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
            }
        }

        final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();

        if (err != START_SUCCESS) {
            if (resultRecord != null) {
                resultStack.sendActivityResultLocked(
                        -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
            }
            ActivityOptions.abort(options);
            return err;
        }
        //检查权限:相当于通告证
        boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,
                resultRecord, resultStack, options);
        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);

        if (mService.mController != null) {
            try {
                // The Intent we give to the watcher has the extra data
                // stripped off, since it can contain private information.
                Intent watchIntent = intent.cloneFilter();
                abort |= !mService.mController.activityStarting(watchIntent,
                        aInfo.applicationInfo.packageName);
            } catch (RemoteException e) {
                mService.mController = null;
            }
        }
        //拦截器:相当于“搜身”,主要为性能统计Profile收集信息
        mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
        mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid,
                options);
        intent = mInterceptor.mIntent;
        rInfo = mInterceptor.mRInfo;
        aInfo = mInterceptor.mAInfo;
        resolvedType = mInterceptor.mResolvedType;
        inTask = mInterceptor.mInTask;
        callingPid = mInterceptor.mCallingPid;
        callingUid = mInterceptor.mCallingUid;
        options = mInterceptor.mActivityOptions;
        if (abort) {
            if (resultRecord != null) {
                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                        RESULT_CANCELED, null);
            }
            // We pretend to the caller that it was really started, but
            // they will just get a cancel result.
            ActivityOptions.abort(options);
            return START_ABORTED;
        }

        //有些情况下部分参数需要重新调整:
        if (mService.mPermissionReviewRequired && aInfo != null) {
            if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                    aInfo.packageName, userId)) {
                IIntentSender target = mService.getIntentSenderLocked(
                        ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
                        callingUid, userId, null, null, 0, new Intent[]{intent},
                        new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
                                | PendingIntent.FLAG_ONE_SHOT, null);

                final int flags = intent.getFlags();
                Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
                newIntent.setFlags(flags
                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
                newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
                if (resultRecord != null) {
                    newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
                }
                intent = newIntent;

                resolvedType = null;
                callingUid = realCallingUid;
                callingPid = realCallingPid;

                rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
                aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
                        null /*profilerInfo*/);

                if (DEBUG_PERMISSIONS_REVIEW) {
                    Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
                            true, false) + "} from uid " + callingUid + " on display "
                            + (mSupervisor.mFocusedStack == null
                            ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId));
                }
            }
        }

        // If we have an ephemeral app, abort the process of launching the resolved intent.
        // Instead, launch the ephemeral installer. Once the installer is finished, it
        // starts either the intent we resolved here [on install error] or the ephemeral
        // app [on install success].
        if (rInfo != null && rInfo.auxiliaryInfo != null) {
            intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
                    callingPackage, verificationBundle, resolvedType, userId);
            resolvedType = null;
            callingUid = realCallingUid;
            callingPid = realCallingPid;

            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
        }

这部分主要工作是:

  • 参数的合法性检查(注意学习err的判断和赋值技巧:虽然有多个独立的if连写,但是最终只会跑其中一个分支)
  • 权限检查
  • 看情况调整部分参数
  • 目前为止还没有开始真正干核心的活

【ActivityStarter.java::startActivity】分析之三

        //P1:创建一个ActivityRecord对象
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, options, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r; //保存到输入参数outActivity数组中
        }

        if (r.appTimeTracker == null && sourceRecord != null) {
            // If the caller didn't specify an explicit time tracker, we want to continue
            // tracking under any it has.
            r.appTimeTracker = sourceRecord.appTimeTracker;
        }

        final ActivityStack stack = mSupervisor.mFocusedStack;
        if (voiceSession == null && (stack.mResumedActivity == null
                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
            //P2:检查调用进程是否有权限切换Application
            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                    realCallingPid, realCallingUid, "Activity start")) {
                //如果AMS当前禁止app switch,则只能把本次启动请求保存起来,以待app switch时再处理。
                PendingActivityLaunch pal =  new PendingActivityLaunch(r,
                        sourceRecord, startFlags, stack, callerApp);
                mPendingActivityLaunches.add(pal);
                ActivityOptions.abort(options);
                return ActivityManager.START_SWITCHES_CANCELED;
            }
        }

        if (mService.mDidAppSwitch) {//用于控制app switch,
            // This is the second allowed switch since we stopped switches,
            // so now just generally allow switches.  Use case: user presses
            // home (switches disabled, switch to home, mDidAppSwitch now true);
            // user taps a home icon (coming from home so allowed, we hit here
            // and now allow anyone to switch again).
            mService.mAppSwitchesAllowedTime = 0;
        } else {
            mService.mDidAppSwitch = true;
        }
        //P3:启动之前因系统禁止appswitch而保存的Pedding请求
        doPendingActivityLaunchesLocked(false);
        //P4:调用另一个startActivity函数
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }

主要工作:

  • 创建ActivityRecord
  • 如果当前AMS禁止app切换,那么将请求保存起来
  • 启动之前因系统禁止app切换而保存的pedding请求
  • 启用真正的启动函数——干真正启动相关的活

P4展开:

【ActivityStarter.java::startActivity】分析之四:另一个startActivity同名函数

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        int result = START_CANCELED;
        try {
            //P1:延时layout
            mService.mWindowManager.deferSurfaceLayout();
            //P2:调用startActivityUncheckedLocked函数
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } finally {
            // 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.
            if (!ActivityManager.isStartResultSuccessful(result)
                    && mStartActivity.getTask() != null) {
                mStartActivity.getTask().removeActivity(mStartActivity);
            }
            mService.mWindowManager.continueSurfaceLayout();
        }
        //P3:Activity启动后的收尾工作
        postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId,  mSourceRecord,
                mTargetStack);

        return result;
    }

真是千呼万唤——还没出来,以为马上要看到嘿啾了,结果发现还有一层内裤。startActivityUnchecked调用是核心,不得不说这个名字起得很贴切,因为从前面的分析看,已经做了诸如参数合法性检查、权限检查、参数调整等,前戏已经做足了,现在是时候直接盘它了!P2展开:

startActivityUnchecked分析

这个函数比较长,但目的比较简单,即为新创建的ActivityRecord找到一个合适的Task。

【ActivityStarter.java::startActivityUnchecked】分析之一

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        //计算TaskFlags,辅助后面判断是否需要创建新的TaskRecord
        computeLaunchingTaskFlags();
        //计算sourceStack
        computeSourceStack();

        mIntent.setFlags(mLaunchFlags);
        //查看是否有可利用的ActivityRecord
        ActivityRecord reusedActivity = getReusableIntentActivity();

        final int preferredLaunchStackId =
                (mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;
        final int preferredLaunchDisplayId =
                (mOptions != null) ? mOptions.getLaunchDisplayId() : DEFAULT_DISPLAY;
        //根据条件查找合适的TaskRecord
        if (reusedActivity != null) {
            // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
            // still needs to be a lock task mode violation since the task gets cleared out and
            // the device would otherwise leave the locked task.
            if (mSupervisor.isLockTaskModeViolation(reusedActivity.getTask(),
                    (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
                mSupervisor.showLockTaskToast();
                Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }

            if (mStartActivity.getTask() == null) {
                mStartActivity.setTask(reusedActivity.getTask());
            }
            if (reusedActivity.getTask().intent == null) {
                // This task was started because of movement of the activity based on affinity...
                // Now that we are actually launching it, we can assign the base intent.
                reusedActivity.getTask().setIntent(mStartActivity);
            }

            // This code path leads to delivering a new intent, we want to make sure we schedule it
            // as the first operation, in case the activity will be resumed as a result of later
            // operations.
            if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                    || isDocumentLaunchesIntoExisting(mLaunchFlags)
                    || mLaunchSingleInstance || mLaunchSingleTask) {
                final TaskRecord task = reusedActivity.getTask();

                // In this situation we want to remove all activities from the task up to the one
                // being started. In most cases this means we are resetting the task to its initial
                // state.
                final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                        mLaunchFlags);

                // The above code can remove {@code reusedActivity} from the task, leading to the
                // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
                // task reference is needed in the call below to
                // {@link setTargetStackAndMoveToFrontIfNeeded}.
                if (reusedActivity.getTask() == null) {
                    reusedActivity.setTask(task);
                }

                if (top != null) {
                    if (top.frontOfTask) {
                        // Activity aliases may mean we use different intents for the top activity,
                        // so make sure the task now has the identity of the new intent.
                        top.getTask().setIntent(mStartActivity);
                    }
                    deliverNewIntent(top);
                }
            }

【ActivityStarter.java::startActivityUnchecked】分析之二

        //P1: 如果目标activity是在当前栈顶,检测一下是它是否只能启动一次
        final ActivityStack topStack = mSupervisor.mFocusedStack;
        final ActivityRecord topFocused = topStack.topActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.realActivity.equals(mStartActivity.realActivity)
                && top.userId == mStartActivity.userId
                && top.app != null && top.app.thread != null
                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || mLaunchSingleTop || mLaunchSingleTask);
        if (dontStart) {
            // For paranoia, make sure we have correctly resumed the top activity.
            topStack.mLastPausedActivity = null;
            if (mDoResume) {
                mSupervisor.resumeFocusedStackTopActivityLocked();
            }
            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.getTask(), preferredLaunchStackId,
                    preferredLaunchDisplayId, topStack.mStackId);

            return START_DELIVERED_TO_TOP;
        }

        boolean newTask = false;
        final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.getTask() : null;

        //P2:确定最终的Task
        int result = START_SUCCESS;
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            //新建task
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
            //如果启动者不为空,则把它的Task作为Task
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            //
            result = setTaskFromInTask();
        } else {
            // This not being started from an existing activity, and not part of a new task...
            // just put it in the top task, though these days this case should never happen.
            setTaskToCurrentTopOrCreateNewTask();
        }
        if (result != START_SUCCESS) {
            return result;
        }

要点:

  • 如果目标Activity已经在栈顶,那么就几乎不用做什么事情了
  • 否则需要进一步确定目标Activity运行于哪一个Task

【ActivityStarter.java::startActivityUnchecked】分析之三

        //P1:这是一个前兆:打印启动Activity的日志,那么就说明马上要真撸了!
        ActivityStack.logStartActivity(
                EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
        mTargetStack.mLastPausedActivity = null;
        //P2:有点眼熟,因为前面已经出现过
        sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
        //P3:目标在目标stack中启动目标acivity
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
        //P4:唤醒逻辑
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                //P4.1:确保Activity可见
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                
                mWindowManager.executeAppTransition();
            } else {
                
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                //P4.2:唤醒聚焦Stack的栈顶Activity
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
        //收尾工作1:更新用户的stack
        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
        //收尾工作2:更新用户的stack
        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,
                preferredLaunchDisplayId, mTargetStack.mStackId);

        return START_SUCCESS;

P3展开:

【ActivityStack.java::startActivityLocked】


    final void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
            boolean newTask, boolean keepCurTransition, ActivityOptions options) {
        TaskRecord rTask = r.getTask();
        final int taskId = rTask.taskId;
        // mLaunchTaskBehind表示任务位于任务堆栈的后面.
        if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
            insertTaskAtTop(rTask, r);
        }
        TaskRecord task = null;
        if (!newTask) {
            //如果是启动一个已经存在的Task,那么找到它
            boolean startIt = true;
            ……
            }
        }
        // 把一个新的Activity放入栈顶,那下一步是与用户交互.
        ……
        if (r.getWindowContainerController() == null) {
            //创建窗口窗口句柄
            r.createWindowContainer();
        }
        task.setFrontOfTask();

        if (!isHomeOrRecentsStack() || numActivities() > 0) {
            ……
            if (r.mLaunchTaskBehind) {
                //如果任务位于任务堆栈的后面,不要打开一个新窗口,更重要的是要通知WMS 
                //r是可见的,即使它在堆栈的后面。
                r.setVisibility(true);
                ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
                ……
                //为新任务打开一个新窗口
                r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
            }
        } else {

            ActivityOptions.abort(options);
        }
    }

P4.2展开:

【ActivityStackSupervisor.java::resumeFocusedStackTopActivityLocked】

boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

        if (!readyToResume()) {
            return false;
        }

        if (targetStack != null && isFocusedStack(targetStack)) {
            //Q1::唤醒栈顶Activity
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            //Q2:唤醒栈顶Activity
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.state == RESUMED) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }

        return false;
    }

Q1与Q2调用了同一个函数,展开:

【ActivityStack.java::resumeTopActivityUncheckedLocked】

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            return false;
        }

        boolean result = false;
        try {
            mStackSupervisor.inResumeTopActivity = true;
            //R1:
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        
        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        if (next == null || !next.canTurnScreenOn()) {
            checkReadyForSleep();
        }

        return result;
    }

R1展开:

【ActivityStack.java::resumeTopActivityInnerLocked】

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        if (!mService.mBooting && !mService.mBooted) {
            // Not ready yet!
            return false;
        }

        //从mHistory中找到第一个需要启动的Activity
        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);

        final boolean hasRunningActivity = next != null;

        ……

        if (!hasRunningActivity) {
            // S1:如果栈中没有Activity,从其它地方找activity
            return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
        }

        next.delayedResume = false;
        ……
        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) {
            //S2:如果该ActivityRecord已有对应的进程存在,则只需要重启Activity,
            //此进程不存在,则要先创建一个应用进程
            ……
        } else {
            //S3: 第一次启动
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    //S4:通知WMS显示启动界面
                    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);
            //S5:调用StackSupervisor的startSpecificActivityLocked
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

该函数很长,这里省略了其中很大的篇幅。

S5展开:

【StackSupervisor.java::startSpecificActivityLocked】 

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        //从AMS中查询是否已经存在满足要求的进程(根据processName和uid来查找)
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        //设置启动时间等信息
        r.getStack().setLaunchTime(r);
        //如果该进程已经存在并已经向AMS注册(例如之前在该进程中启动了其他Activity)
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {

                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                //通知该进程中的启动目标Activity
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }
        }
        //如果该进程不存在,则需要调用AMS的startProcessLocked创建一个应用进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

AMS中的startProcesLocked函数将创建一个新的应用进程,下面将分析这个函数。

【ActivityManagerService.java::startProcessLocked】

    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        //调用另一个startProcessLocked
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }

在早期的版本中,这个函数有FLAG_FROM_BACKGROUND等相关的逻辑,新版本显然是优化掉了

【ActivityManagerService.java::startProcessLocked】

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        long startTime = SystemClock.elapsedRealtime();
        ProcessRecord app;
        if (!isolated) {
            //查找ProcessRecord
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            ……
            }
        } else {
            // If this is an isolated process, it can't re-use an existing process.
            app = null;
        }

        
        ……
        //如果已经有可用的ProcessRecord,则不用创建新的进程
        if (app == null) {
            //没找到可用ProcessRecord,新建一个
            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
            if (app == null) {
                Slog.w(TAG, "Failed making new process record for "
                        + processName + "/" + info.uid + " isolated=" + isolated);
                return null;
            }
            app.crashHandler = crashHandler;
            checkTime(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.versionCode, mProcessStats);
            checkTime(startTime, "startProcess: added package to existing proc");
        }

        //如果系统还没ready,则把它放入mProcessesOnHold中去,以后再伺机启动
        // process until it is.
        if (!mProcessesReady
                && !isAllowedWhileBooting(info)
                && !allowWhileBooting) {
            if (!mProcessesOnHold.contains(app)) {
                mProcessesOnHold.add(app);
            }
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
                    "System not ready, putting on hold: " + app);
            checkTime(startTime, "startProcess: returning with proc on hold");
            return app;
        }

        //又另一个startProcessLocked
        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
        checkTime(startTime, "startProcess: done starting proc!");
        return (app.pid != 0) ? app : null;
    }

【ActivityManagerService.java::startProcessLocked】

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        ……

        //mProcessesOnHold用于保存那些在系统还没有准备好就提前请求启动的ProcessRecord
        mProcessesOnHold.remove(app);
        ……
        try {
            ……
            if (hostingType.equals("webview_service")) {
                ……
            } else {
                //发送消息给Zygote,它将派生一个子进程,该子进程执行ActivityThread的main函数
                //注意,我们传递给Zygote的参数并没有包含任何与Activity相关的信息。
                //现在仅仅启动一个应用进程
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, entryPointArgs);
            }
            ……
            //把app的pid设置成刚新建的进程id
            app.setPid(startResult.pid);
            ……
            //关心刚才创建的进程是不是com.android.phone
            if (app.persistent) {
                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
            }

            ……
            synchronized (mPidsSelfLocked) {
                //以pid为key,将代表该进程的ProcessPrecord对象加入到mPidsSelfLocked中保管                this.mPidsSelfLocked.put(startResult.pid, app);
                if (isActivityProcess) {
                    //发送一个超时消息,如果这个新创建的应用进程10秒内没有和AMS交互,则可断定
                    //该应用启动失败
                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                    msg.obj = app;
                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
                }
            }
            checkTime(startTime, "startProcess: done updating pids map");
        } catch (RuntimeException e) {
            ……
        }
    }

重要函数调用关系

简化上述函数调用顺序如下:

ActivityManagerService.java::startActivity(){
  ActivityStarter.java::startActivityMayWait(){
    ActivityStarter.java::startActivityLocked(){
      ActivityStarter.java::startActivity(){
        ActivityStarter.java::startActivityUnchecked(){
          //P51:启动一个Activity
          ActivityStack.java::startActivityLocked()
          //P52:唤醒栈顶Activity
          ActivityStackSupervisor.java::resumeFocusedStackTopActivityLocked(){
            ActivityStack.java::resumeTopActivityUncheckedLocked(){
              ActivityStack.java::resumeTopActivityInnerLocked(){
                StackSupervisor.java::startSpecificActivityLocked(){
                   //91:如果app!=null
                   realStartActivityLocked()
                   //92:否则:启动一个应用
                   ActivityManagerService.java::startProcessLocked(){
                     //通知Zygote派生一个子进程
                     Process::start()
          }}}}}
        }
}}}}

发布了90 篇原创文章 · 获赞 24 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/menghaocheng/article/details/104067428