美文网首页
Android9.0 AMS之应用Task创建流程

Android9.0 AMS之应用Task创建流程

作者: android_coder | 来源:发表于2019-07-25 14:54 被阅读0次

    1:activity启动过程中涉及到的主要类

    Activitymanagerservice.java 主要是负责四大组件的启动和管理,进程调度,消息和四大组件的生命周期等
    Activity.java 主要是提供给应用程序使用的组件
    ActivityRecord.java 服务端的activity组件,在activity启动过程中创建
    TaskRecord.java 用来管理ActivityRecord,以栈的形式来管理
    ActivityStarter.java 用来负责activity的启动,将intent信息和启动的flag转化为ActivityRecord和确定TaskRecord
    ActivityStack.java 用来管理TaskRecord的,目前ActivityStack的类型是有限的
    ActivityThread.java 应用程序的主线程

    2:activity启动流程分析

    2.1桌面启动应用的逻辑
    test.png

    Intent.FLAG_ACTIVITY_NEW_TASK表示的是要启动一个新的task,但是并不是在intent上加上了此flags,被启动的activity就和该activity在不同的task中

    2.2startActivity的逻辑实现
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
    

    我们可以看到是通过ActivityManager调用getService方法后来启动activity的,得到的是远程服务端AMS的代理对象

    2.3ActivityManagerService的startActivity方法

    startActivity方法会调用两个同名的startActivityAsUser方法

      // TODO: Switch to user app stacks here.
      return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                    .setCaller(caller)
                    .setCallingPackage(callingPackage)
                    .setResolvedType(resolvedType)
                    .setResultTo(resultTo)
                    .setResultWho(resultWho)
                    .setRequestCode(requestCode)
                    .setStartFlags(startFlags)
                    .setProfilerInfo(profilerInfo)
                    .setActivityOptions(bOptions)
                    .setMayWait(userId)
                    .execute();
    

    通过获取一个ActivityStarter的对象,然后调用其execute方法

    2.4ActivityStarter的execute方法
        int execute() {
            try {
                // TODO(b/64750076): Look into passing request directly to these methods to allow
                // for transactional diffs and preprocessing.
                if (mRequest.mayWait) {-------->由于在2.3调用了setMayWait方法,因此这个地方是true
                    return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                            mRequest.callingPackage, 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);
                } 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);
                }
            } finally {
                onExecutionComplete();
            }
        }
    
    2.5ActivityStarter之startActivityMayWait
     final ActivityRecord[] outRecord = new ActivityRecord[1];
     int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
              voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
              callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
              ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
              allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
    

    这个方法的前半部分主要是根据intent信息和flag信息解析出一个ActivityInfo的对象,然后调用startActivity方法来启动一个activity

    2.6ActivityStarter之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,
                SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
                ActivityRecord[] outActivity, TaskRecord inTask, String reason,
                boolean allowPendingRemoteAnimationRegistryLookup,
                PendingIntentRecord originatingPendingIntent) {
            if (TextUtils.isEmpty(reason)) {
                throw new IllegalArgumentException("Need to specify a reason.");
            }
            mLastStartReason = reason;
            mLastStartActivityTimeMs = System.currentTimeMillis();
            mLastStartActivityRecord[0] = null;
            mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                    callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                    inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
            if (outActivity != null) {
                // mLastStartActivityRecord[0] is set in the call to startActivity above.
                outActivity[0] = mLastStartActivityRecord[0];
            }
            return getExternalResult(mLastStartActivityResult);
    

    这个方法是调用了同名的startActivity方法,接着继续调用同名的方法

    2.7ActivityStarter之startActivity
       // 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*/);
            }
            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;
            }
    ..........................................................................................
     return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                    true /* doResume */, checkedOptions, inTask, outActivity);
    

    这个方法主要是分两部分,第一部分是构建AMS端的一个Activity对象ActivityRecord,第二部分是继续调用startActivity方法

    2.8ActivityStarter之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 {
                mService.mWindowManager.deferSurfaceLayout();
                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.
                final ActivityStack stack = mStartActivity.getStack();
                if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
                    stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                            null /* intentResultData */, "startActivity", true /* oomAdj */);
                }
                mService.mWindowManager.continueSurfaceLayout();
            }
            postStartActivityProcessing(r, result, mTargetStack);
            return result;
        }
    
    2.9ActivityStarter之startActivityUnchecked
       boolean newTask = false;
            final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            // Should this be considered a new task?
            int result = START_SUCCESS;
            if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                    && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {--------->这四个条件决定是否需要创建新的task
                newTask = true;
                result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
            } else if (mSourceRecord != null) {
                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;
            }
    
    2.10ActivityStarter之setTaskFromReuseOrCreateNewTask
        private int setTaskFromReuseOrCreateNewTask(
                TaskRecord taskToAffiliate, ActivityStack topStack) {
            mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);----->计算焦点栈(ActivityStack)
            // Do no move the target stack to front yet, as we might bail if
            // isLockTaskModeViolation fails below.
            if (mReuseTask == null) {
                final TaskRecord task = mTargetStack.createTaskRecord(------------>创建Task
                        mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                        mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                        mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
                        mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
                        mOptions);
                addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
                updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
                if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
                        + " in new task " + mStartActivity.getTask());
            } else {
                addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
            }
            if (taskToAffiliate != null) {
                mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
            }
            if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            if (mDoResume) {
                mTargetStack.moveToFront("reuseOrNewTask");
            }
            return START_SUCCESS;
        ```
    #####2.11ActivityStack之createTaskRecord
    
    TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            boolean toTop, ActivityRecord activity, ActivityRecord source,
            ActivityOptions options) {
        final TaskRecord task = TaskRecord.create(
                mService, taskId, info, intent, voiceSession, voiceInteractor);---->创建一个TaskRecord
        // add the task to stack first, mTaskPositioner might need the stack association
        addTask(task, toTop, "createTaskRecord");
        final int displayId = mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY;
        final boolean isLockscreenShown = mService.mStackSupervisor.getKeyguardController()
                .isKeyguardOrAodShowing(displayId);
        if (!mStackSupervisor.getLaunchParamsController()
                .layoutTask(task, info.windowLayout, activity, source, options)
                && !matchParentBounds() && task.isResizeable() && !isLockscreenShown) {
            task.updateOverrideConfiguration(getOverrideBounds());
        }
        //创建一个TaskWindowContainerController,关联wms端的Task
        task.createWindowContainer(toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
        return task;
    }
    
    这样一个新的Task(TaskRecord)便创建完成
    
    

    相关文章

      网友评论

          本文标题:Android9.0 AMS之应用Task创建流程

          本文链接:https://www.haomeiwen.com/subject/mqgcrctx.html