深入AMS源码(二)—— ActivityManagerService对Activity的调度管理

1、概述

在上一篇深入AMS源码(一)——ActivityManagerService的基础知识文章介绍了AMS的基础信息,主要包括AMS中主要的数据结构、主要功能类和属性以及AMS中对生命周期的调度方式,本篇主要从源码的角度分析下AMS对Activity的调度逻辑,这也是AMS的主要功能;

2、源码分析

  • AMS.startActivity()
    关于Activity的启动过程查Android进阶知识树——Android四大组件启动过程,Activity的启动会执行到AMS.startActivity(),在AMS.startActivity()中直接逐次调用startActivityAsUser()的重载方法
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
        boolean validateIncomingUser) {
    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    return mActivityStartController.obtainStarter(intent, "startActivityAsUser”)  // 创建ActivityStarter对象
            .setCaller(caller) // 设置回调的Application对象
            .setCallingPackage(callingPackage) // 设置发起请求的包名
            .setResolvedType(resolvedType)
            .setResultTo(resultTo) // 设置setResult返回数据的Record对象,即调用startActivityForResult()的活动
            .setResultWho(resultWho) 
            .setRequestCode(requestCode) // 设置请求码
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId) // 所属用户ID
            .execute(); // 执行execute()
}

最终在startActivityAsUser()方法中,执行mActivityStartController.obtainStarter()创建ActivityStarter对象并初始化数据,调用execute()程序进入ActivityStarter类中

int execute() {
    try {
        if (mRequest.mayWait) {  //首次进入执行mayWait()
            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                  …….
            mRequest.allowPendingRemoteAnimationRegistryLookup);
        } else {
            return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                  …….
            mRequest.allowPendingRemoteAnimationRegistryLookup);
        }
    } 
}

在设置userId是已经将mayWait设置为true了,所以execute()中会执行startActivityMayWait()方法

 final int startActivityMayWait(){
boolean componentSpecified = intent.getComponent() != null; // 1、
 
final int realCallingPid = Binder.getCallingPid(); // 获取当前进程的Uid
final int realCallingUid = Binder.getCallingUid();
final Intent ephemeralIntent = new Intent(intent); // 创建备份的Intent
intent = new Intent(intent); // 创建新的intent

 //(2)
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
        0 /* matchFlags */,computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));
        
//(3)
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
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);

在startActivityMayWait()中主要执行四个操作

  1. 判断当前Intent中是否含有数据,并创建新的Intent对象封装数据
  2. 校验PMS中扫描到的mActivities集合中能处理Intent的ResolveInfo,查询不到则失败;
  3. 查找启动的目标活动对应的ActivityInfo
  4. 调用startActivity()执行Activity启动
  • mSupervisor.resolveIntent()
mService.getPackageManagerInternalLocked().resolveIntent( 
        intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
PackageManagerInternal getPackageManagerInternalLocked() {
    if (mPackageManagerInt == null) {
        mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class); // 获取PackageManagerInternalImpl()
    }
    return mPackageManagerInt;
}

在PMS启动完成后,会使用LocalService注册PackageManagerInternalImpl()对象,它是PMS的内部类;

LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());

通过LocalServices对象调用的实际是PackageManagerInternalImpl.resolveIntent()中的方法,resolveIntent()中又调用resolveIntentInternal()方法

private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
        int flags, int userId, boolean resolveForStart, int filterCallingUid) {
    try {
        if (!sUserManager.exists(userId)) return null; // 1、检查程序的userId
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart);//2、更新Flag
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
       //3、从PMS遍历后保存的Intent-filter结合中查询能处理Intent的ResolveInfo的集合
        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
                flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/); 
      
        final ResolveInfo bestChoice =
                chooseBestActivity(intent, resolvedType, flags, query, userId);//4、匹配最好的ResolveInfo
        return bestChoice; // 返回ResolveInfo
    } 
}

在resolveIntentInternal()中回调用queryIntentActivitiesInternal()查询匹配的集合,这里实际是通过PMS中完成的,PMS中会遍历保存的四大组件信息的集合匹配能处理的信息对象,具体匹配细节见另一篇问文章深入PMS源码(三)—— PMS中intent-filter的匹配架构,在匹配成功后返回一个符合条件的集合,然后调用chooseBestActivity选择并返回最合适的ResolveInfo对象,之后继续执行下面的resolveActivity()

  • mSupervisor.resolveActivity()
ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags,
        ProfilerInfo profilerInfo) {
    final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null; // 1、获取其中的ActivityInfo对象
    if (aInfo != null) {
        intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));//2、设置Component对象
        final String intentLaunchToken = intent.getLaunchToken();
        if (aInfo.launchToken == null && intentLaunchToken != null) {
            aInfo.launchToken = intentLaunchToken;
        }
    }
    return aInfo; // 返回aInfo对象
}

resolveActivity()中逻辑很简单,根据查询获取到的ResolveInfo获取其中的ActivityInfo对象,并将信息封装在Component对象中,最后赋值给Intent对象,此时Component中就包含着要启动的真正对象;

  • startActivity()
ProcessRecord callerApp =  mService.getRecordForAppLocked(caller); // 1、

ActivityRecord sourceRecord = null; // 保存请求启动的父Activity
ActivityRecord resultRecord = null; // 保存结果返回的resultCode
if (resultTo != null) { // 处理resultTo回传数据
    sourceRecord = mSupervisor.isInAnyStackLocked(resultTo); //  2、
    if (sourceRecord != null) {
        if (requestCode >= 0 && !sourceRecord.finishing) {
            resultRecord = sourceRecord; // 默认赋值resultRecord为启动者所在的栈
        }
    }
}
 int launchFlags = intent.getFlags(); // 3、
 //Intent.FLAG_ACTIVITY_FORWARD_RESULT:处理跨Activity回传结果问题,这里主要针对在第一个Activity启动但需要在第三个activity返回数据
if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
 ……….
}
//初始化ActivityStack,默认使用resultRecord中TaskStack所属的管理类
final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho, // 4、
        requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
        inTask != null, callerApp, resultRecord, resultStack); 
if (mService.mController != null){// 5、
Intent watchIntent = intent.cloneFilter();
abort |= !mService.mController.activityStarting(watchIntent,aInfo.applicationInfo.packageName);
}  
mInterceptor.intercept(..) // 执行拦截器的intercept()
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,  //6、
        callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
        resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
        mSupervisor, checkedOptions, sourceRecord);
final ActivityStack stack = mSupervisor.mFocusedStack; // 获取当前交互的ActivityStack
// 7、
If(!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start”) ){
   mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
        sourceRecord, startFlags, stack, callerApp));
}
mController.doPendingActivityLaunchesLocked(false); // 8、
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
        true /* doResume */, checkedOptions, inTask, outActivity); // 9、

在startActivity()中执行了许多主要的功能,具体如下:

  1. 根据调用传入的IApplication对象,从AMS的mLruProcesses集合中获取当前进程信息;
  2. 根据保存的resultTo取出要回传数据的Record,即发起启动的Activity,主要针对setActivityForRequest()方法
  3. 获取设置的Flag信息,处理跨Activity回传信息标识
  4. 初始化ActivityStack对象,执行检查权限信息
  5. 执行AMS中的IActivityController对象,主要用于监听AMS启动过程
  6. 创建临时的ActivityRecord信息保存所有的请求信息
  7. 检验是否允许切换活动,如果当前进程暂停切换,则创建延迟意图PendingIntent保存启动信息,添加到mPendingActivityLaunches集合中;
  8. 判断mPendingActivityLaunches是否有任务,优先执行存在的延时任务
  9. 通过上面的层层检查后,调用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 {
        mService.mWindowManager.deferSurfaceLayout(); // 调用WindowManager处理绘制
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity); //调用startActivityUnchecked()
    } finally {.
        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;
}
  • 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); // 1、初始化ActivityStarter每个属性信息
computeLaunchingTaskFlags(); //2、计算目标活动的Flag
computeSourceStack(); // 3、计算活动的任务栈Stack
mIntent.setFlags(mLaunchFlags); 设置新的Flag
ActivityRecord reusedActivity = getReusableIntentActivity(); //4、从mHistory历史栈中匹配已经存在的Record对象,准备复用此对象
if (reusedActivity != null) {
if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
    mStartActivity.setTask(reusedActivity.getTask()); // 设置目标活动栈为要复用Activity的所在stack栈
}
if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
        || isDocumentLaunchesIntoExisting(mLaunchFlags)
        || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {// 5、处理clearTop模式,清空之上的Record
    final TaskRecord task = reusedActivity.getTask();
    final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
            mLaunchFlags); //移除目标mStartActivity之上的活动,返回目标record;
if (top.frontOfTask) {
    top.getTask().setIntent(mStartActivity); // 如果top为栈中第一个则设置启动的ActiivityRecord
}
// 6、找到要复用目标所在的栈,并将其移动到ActivityStack的最上面,同时设置mFocusStack;
reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);

 final ActivityRecord outResult = // 取出要启动的目标Activity
                    outActivity != null && outActivity.length > 0 ? outActivity[0] : null;

if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { // 7、只需将Activity放置在前台,不需要启动(桌面点击已启动程序图标时)
    resumeTargetStackIfNeeded();
    return START_RETURN_INTENT_TO_CALLER;
}
setTaskFromIntentActivity(reusedActivity); // 8、根据mLaunchFlags和resumeActiivity处理最终的Task的选择

//取出当前活动栈顶的ActivityRecord
final ActivityStack topStack = mSupervisor.mFocusedStack;
final ActivityRecord topFocused = topStack.getTopActivity(); // 从mHistory中获取最顶的Activity
final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop); //9、
final boolean dontStart = top != null && mStartActivity.resultTo == null  // 此时topActivity和目标Activity一致
        && top.realActivity.equals(mStartActivity.realActivity)
        && top.userId == mStartActivity.userId
        && top.app != null && top.app.thread != null
        && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
        || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
if (dontStart) 
    if (mDoResume) {
        mSupervisor.resumeFocusedStackTopActivityLocked();//此时只需要将要重用的ActivityRecord,重新resume即可
    }
    deliverNewIntent(top); //发送NewIntent
    return START_DELIVERED_TO_TOP;
}
boolean newTask = false;
int result = START_SUCCESS; //10、对于没有复用的模式,处理要启动Activity的Task
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
    newTask = true;
    result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);//创建新的TaskRecord
} else if (mSourceRecord != null) {
    result = setTaskFromSourceRecord(); // 从mSourceRecord中获取stack,并将stack移动到最前端
} else if (mInTask != null) {
    result = setTaskFromInTask(); // 从mInTask中获取task
} else {
    setTaskToCurrentTopOrCreateNewTask(); // 其他情况处理
}
if (result != START_SUCCESS) {
    return result;
}
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
        mOptions); // 12、对与没有或不能复用的情况,直接启动Activity实例
}

startActivityUnchecked()方法很长,但其中的功能很主要,下面一一分析相应的功能逻辑:

  1. 调用setInitialState()方法,根据现有信息重新设置成员属性
private void setInitialState() {
reset(false /* clearRequest */); // 重置ActivityStarter对象属性
mStartActivity = r;
mIntent = r.intent;
mOptions = options;
mCallingUid = r.launchedFromUid;
mSourceRecord = sourceRecord;
mVoiceSession = voiceSession;
mVoiceInteractor = voiceInteractor;
mLaunchMode = r.launchMode;//初始化launchMode
mLaunchFlags = adjustLaunchFlagsToDocumentMode(r, LAUNCH_SINGLE_INSTANCE == mLaunchMode, // 根据launchMode调整Flags
LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
}
  1. 执行computeLaunchingTaskFlags()计算LaunchFlag中是否需要添加NewTask标志
private void computeLaunchingTaskFlags() {
    if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
        final Intent baseIntent = mInTask.getBaseIntent();
        final ActivityRecord root = mInTask.getRootActivity();
if (root == null) { // 如果此时stack为空,则将目标ActivityRecord作为根Record
    final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
            | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
    mLaunchFlags = (mLaunchFlags & ~flagsOfInterest) | (baseIntent.getFlags() & flagsOfInterest);
    mIntent.setFlags(mLaunchFlags);
    mInTask.setIntent(mStartActivity); // 设置根Record对象
    mAddingToTask = true;
} else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
    mAddingToTask = false; // 对于NewTask设置为false,创建新的NewTask
} else {
    mAddingToTask = true;
}
mReuseTask = mInTask;
}else {
            mInTask = null;
            if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
                    && mSourceRecord.inFreeformWindowingMode())  {
                mAddingToTask = true;
            }
        }
}
if (mInTask == null) {
            if (mSourceRecord == null) {
                if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
                    mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
                }
            } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            }
        }

(1). 如果mInTask不为空,则说名当前请求已经设置了要求加入的TaskStack中,然后判断mInTask中是否为空,如果为空则将当前活动作为根部活动保存ActivityRecord信息,如果mInTask不为空且设置了NewTask标志,则将mAddingToTask只为false表示需要创建新的Task对象;
(2) 如果未制定mInTask对象,则判断父类的Task是否可用,如果可用则将目标Activity启动到父Activity的栈中;
(3) 最后设置mLaunchFlags属性,如果mSourceRecord为空、或父mSourceRecord指定Single_Instance模式、目标活动设置的Single模式,则添加NewTask标志;
3. 调用computeSourceStack()处理父Activity栈的记录问题

private void computeSourceStack() {
    if (!mSourceRecord.finishing) { // 获取发起启动Activity的所在栈
        mSourceStack = mSourceRecord.getStack();
        return;
    }
    if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) { // 处理NEW_TASK标志启动新的栈
        mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; // 添加NewTask标志
        mNewTaskInfo = mSourceRecord.info; // 并保存原来的taskInfo、Intent
        final TaskRecord sourceTask = mSourceRecord.getTask();
        mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
    }
    mSourceRecord = null;
    mSourceStack = null;
}

如果mSourceRecord为空直接返回null,如果mSourceRecord存在且没有finish则获取其所在的栈保存在mSourceStack中,如果父mSourceRecord的finishing为true,则表示当前Activity即将销毁,那就不能使用其所在的栈,此时会创建一个新栈对象然后保存mSourceRecord的栈信息;

  1. getReusableIntentActivity():查找是否存在可以复用的对象
private ActivityRecord getReusableIntentActivity() { // 设置NewTask但未设置MULTIPLE_TASK,此时可以复用Activity
boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&(mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)|| isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK); // 处理可以复用ActivityRecord的FLAG
ActivityRecord intentActivity = null;
if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
    final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
    intentActivity = task != null ? task.getTopActivity() : null;
} else if (putIntoExistingTask) {
    if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
       intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
               mStartActivity.isActivityTypeHome()); // 针对Single_instance模式查找对应的ActivityRecord
    } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
        intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
                !(LAUNCH_SINGLE_TASK == mLaunchMode)); // 
    } else {
        intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId); //从历史记录中查找
    }
}
return intentActivity;
}

在getReusableIntentActivity()中,首先判断是否设置NewTask但未设置MULTIPLE_TASK标志、是否设置LAUNCH_SINGLE_INSTANCE或LAUNCH_SINGLE_TASK标志,因为这几种情况下是可以从栈中复用Activity的,
(1)对于mOptions中设置了TaskId的,根据TaskId取出相应的task并获取顶部的活动
(2)对于LAUNCH_SINGLE_INSTANCE模式的调用findActivityLocked()查找ActivityRecord
(3)对于其他的情况直接调用findTaskLocked()从历史记录中查找信息
5. 处理clearTop模式,清空之上的Record
6. setTargetStackAndMoveToFrontIfNeeded()将复用的栈移动到最顶部位置

private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
mTargetStack = intentActivity.getStack(); // 要查找的目标栈
final ActivityStack focusStack = mSupervisor.getFocusedStack();
ActivityRecord curTop = (focusStack == null)
        ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop); // 获取当前栈,并从栈中获取最顶层的ActivityRecord
final TaskRecord topTask = curTop != null ? curTop.getTask() : null; // 此时处于最上面的TaskRecord
if (topTask != null // 如果最顶部的TaskStack并不是目标需要的栈
        && (topTask != intentActivity.getTask() || topTask != focusStack.topTask())
        && !mAvoidMoveToFront) {
    mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); // 添加移动TaskRecord的标志
mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions, // 将目标栈移动到栈顶
        mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
mMovedToFront = true;
}

在setTargetStackAndMoveToFrontIfNeeded()中查找到要复用的ActivityRecord所在的栈,然后获取当正在交互的focusStack,如果二者不同则调用moveTaskToFrontLocked()将要复用的栈移动到ActivityStack的最前面;

  1. setTaskFromIntentActivity():处理TaskStack中的任务
private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {// 处理clear_task清空所在的栈task
    final TaskRecord task = intentActivity.getTask();
    task.performClearTaskLocked(); // 清空所有Record
    mReuseTask = task;
    mReuseTask.setIntent(mStartActivity); // 设置目标活动为root ActivityRecord
} else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 //clear_top
        || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
    ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,mLaunchFlags);
} else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
    if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || LAUNCH_SINGLE_TOP == mLaunchMode)
            && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
        if (intentActivity.frontOfTask) {
            intentActivity.getTask().setIntent(mStartActivity); // 当前顶部的活动就是要启动的目标活动
        }
        deliverNewIntent(intentActivity);
    } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
        mAddingToTask = true;
        mSourceRecord = intentActivity;
    }
} else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {// 通知、图标快捷方式启动时
    mAddingToTask = true;
    mSourceRecord = intentActivity;
} else if (!intentActivity.getTask().rootWasReset) {
    intentActivity.getTask().setIntent(mStartActivity);
}
}

在setTaskFromIntentActivity()中,如果设置了FLAG_ACTIVITY_CLEAR_TASK标志,则清除栈中所有的ActivityRecord并将目标活动设置为Task的根部活动,继续处理CLEAR_TOP、FLAG_ACTIVITY_SINGLE_TOP标志的清除工作;

  1. 调用topRunningNonDelayedActivityLocked()返回历史记录中最上面的可resume的ActivityRecord,前面的处理知道已经将复用的栈移动到最前面且清空了复用栈之上的所有ActivityRecord对象,那此时取出的就是要复用的对象,比较相应的模式和对象相等后此时只需将活动resume即可;
  2. 对于没有复用的模式,处理要启动Activity的Task,此处会针对情况创建新Task
  3. 对与没有或不能复用的情况,直接启动Activity创建新的实例

2.1 显示复用的活动

对于已经能复用且已经找到复用ActivityRecord对象的,直接调用ActivityStack的resumeTopActivityInnerLocked()实现Resume复用的ActivityRecord对象;

  • resumeTopActivityInnerLocked():
ActivityRecord next = topRunningActivityLocked(null); //1、
 if (next == null) {
    if (mMainStack) {
      return mService.startHomeActivityLocked(); // 
    }
}
 next.delayedResume = false;
// 2、
if (mResumedActivity == next && next.state == ActivityState.RESUMED)  { 
}
mStackSupervisor.mStoppingActivities.remove(next); // 3、
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
if (!mStackSupervisor.allPausedActivitiesComplete()) {// 4、
    return false;
}
if (mResumedActivity != null) { // 5、
    pausing |= startPausingLocked(userLeaving, false, next, false); // 执行暂停
}
if (pausing && !resumeWhilePausing) {
    if (next.app != null && next.app.thread != null) {
        mService.updateLruProcessLocked(next.app, true, null); // 6、
    }
    return true;
} else if (mResumedActivity == next && next.isState(RESUMED)
        && mStackSupervisor.allResumedActivitiesComplete()) {
    return true;
}

在resumeTopActivityInnerLocked()中实现对父活动的暂停操作,和新Activity的resume过程:

  1. 获取mHistory中第一个Activity,因为前面已经将要启动的目标添加为第一个,此时如果mHistory中没有活动记录,则启动Main界面;
  2. 判断当前resumed的活动和目标活动是否一致,一致不做任何操作;
  3. 从Stop和WaitingVisiable集合中移除信息,因为该活动即将被启动;
  4. 判断是否有活动正在停止,如果直接返回false,不能执行启动任务
  5. 如果存在正在交互的活动,需要先暂停正在交互的活动
  6. 将要启动的Activity所在的进程添加到mLruProcesses集合中

在执行上述过程后AMS中的处理过程就完成了,在第五步中判断当前是否存在正在交互的活动,如果存在则先执行去暂停操作,即回调onPause()方法,AMS‘回到的方法使用LifecycleManager具体过程见AMS中Activity生命周期回调,方法会执行到ActivityThread中执行活动的handlePauseActivity()

@Override
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
        int configChanges, PendingTransactionActions pendingActions, String reason) {
    ActivityClientRecord r = mActivities.get(token); // 从保存的Activity列表中返回
    if (r != null) {
        performPauseActivity(r, finished, reason, pendingActions); 
    }
}
  • performPauseActivity(): Android P 中处理Activity暂停的方法
if (!r.activity.mFinished && saveState) { // 对于pause的活动回调onSaveInstanceState()保存数据
       state = new Bundle();
       mInstrumentation.callActivitycallActivityOnSaveInstanceState(r.activity, state); 
       r.state = state; // 保存包含数据的state
 }
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity); // 调用onPause()
r.paused = true;

在performPauseActivity中首先回到Activity的callActivityOnSaveInstanceState()方法,大家都知道此方法是保存界面数据,在界面重建时可以回复数据的,然后执行Activity的onPause()方法,在执行完之后会回调AMS.activityPaused()方法通知暂停结束,AMS可以继续执行任务,在activityPaused()中调用了completePauseLocked()方法;

  • completePauseLocked():执行onPause()事件结束完毕后回调
 ActivityRecord prev = mPausingActivity; // 1、
boolean wasStopping = prev.isState(STOPPING);
prev.setState(PAUSED, "completePausedLocked");

prev.waitingVisible = false; // 设置状态
mWaitingVisibleActivities.remove(prev);
if (prev.finishing) { // 结束当前Activity
    prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,"completedPausedLocked");
} 
if (prev.app != null) {
mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)

if (!prev.visible || shouldSleepOrShutDownActivities()) {
    prev.setDeferHidingClient(false);
    addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */); //将执行了pause()的活动加入stopping集合中
}
   }
}
 mPausingActivity = null; // 指控mPausingActivity
if (resumeNext) { // 继续处理目标Activity的Resume
    final ActivityStack topStack = mStackSupervisor.getFocusedStack();
    if (!topStack.shouldSleepOrShutDownActivities()) {
        mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null); // 执行Activity的resume()
    } else {
        ActivityRecord top = topStack.topRunningActivityLocked();
        if (top == null || (prev != null && top != prev)) {
        mStackSupervisor.resumeFocusedStackTopActivityLocked();
        }
    }
}

在completePauseLocked中获取当前Pause的ActivityRecord,设置状态属性并清空mPausingActivity,如果ActivityRecord设置finish为true则执行销毁操作,然后调用addToStopping()将ActivityRecord加入到mStoppingActivities集合中,当存在需要启动的活动时,会从栈顶取出ActivityRecord并执行resumeFocusedStackTopActivityLocked()方法显示活动;

  • resumeTopActivityInnerLocked():在处理paused后会继续执行resumeTopActivityInnerLocked(),此时传入prev
if (prev != null && prev != next) {
    if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
            && next != null && !next.nowVisible) {
     mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev); // 加入 WaittingVisiable集合
    } else {
        if (prev.finishing) {
            prev.setVisibility(false);
    }
}
。。。。。。。
mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); // 处理WMS执行动画窗口切换
 if (next.app != null && next.app.thread != null) { // 1、判断目标活动的进程是否启动,此时是Resumed的活动
if (!next.visible || next.stopped || lastActivityTranslucent) {
    next.setVisibility(true); // 设置visibility为true
}
final ActivityState lastState = next.getState();
next.setState(RESUMED, "resumeTopActivityInnerLocked”); // 设置State为resume
mService.updateLruProcessLocked(next.app, true, null); // 2、

final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
        next.appToken);
transaction.addCallback(ActivityResultItem.obtain(a));
if (next.newIntents != null) {
    transaction.addCallback(NewIntentItem.obtain(next.newIntents,false /* andPause */));// 回调onNewIntent()
}
transaction.setLifecycleStateRequest(
        ResumeActivityItem.obtain(next.app.repProcState,
                mService.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);// 3、
}else{
mStackSupervisor.startSpecificActivityLocked(next, true, true); //4、对于新创建的ActivityRecord,其中的app和app.thread = null
}

resumeTopActivityInnerLocked()中将prev对象加入 WaittingVisiable集合中,然后调用WMS处理窗口切换操作,最后执行显示过程:

  1. 判断目标活动的进程是否启动,如果启动则将可见性设为true并更新ActivityRecord的状态
  2. 更新最近使用的进程集合
  3. 执行调用ActivityThread的handleResumeActivity(),内部同样使用LifecycleManager机制
  4. 对于新创建的ActivityRecord内部进程信息为null,则调用startSpecificActivityLocked()方法处理
  • ActivityThread.handleResumeActivity
ActivityClientRecord r = performResumeActivity(token, clearHide); // 执行Activity的onResume()
View decor = r.window.getDecorView(); // 处理Window添加DecorView、Activity配置变化、输入法等窗口问题
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
if (!a.mWindowAdded) {
    a.mWindowAdded = true;
    wm.addView(decor, l);
}
if ((l.softInputMode
        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
        != forwardBit) { // 处理输入法对界面的改变
    l.softInputMode = (l.softInputMode
            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) | forwardBit;
    if (r.activity.mVisibleFromClient) {
        ViewManager wm = a.getWindowManager();
        View decor = r.window.getDecorView();
        wm.updateViewLayout(decor, l);
    }
}
if (r.activity.mVisibleFromClient) {
    r.activity.makeVisible(); // 调用WMS添加视图View到窗口中
}
r.nextIdle = mNewActivities;
mNewActivities = r;
Looper.myQueue().addIdleHandler(new Idler());  // 加入一个Idler对象,处理内存消息机制

执行了onResume()的活动此时即处于可交互的状态,到此活动的复用启动结束;

2.2 创建新对象启动活动

对于未找到匹配的ActivityRecord实例,需要判断进程是否启动或重新创建Activity对象,此时在resumeTopActivityLocked()中,会调用 startSpecificActivityLocked(next, true, true)

  • startSpecificActivityLocked()
private final void startSpecificActivityLocked(ActivityRecord r,
595            boolean andResume, boolean checkConfig) {
597        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
598                r.info.applicationInfo.uid); // 1、
           getLaunchTimeTracker().setLaunchTime(r); // 设置启动时间
609        if (app != null && app.thread != null) { // 判断进程是否启动
611       realStartActivityLocked(r, app, andResume, checkConfig); // 2、进程已启动的直接执行创建Activity实例
612                return;
613         } 
622        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, // 3、进程未启动的,先启动进程
623                "activity", r.intent.getComponent(), false);
624    }

在startSpecificActivityLocked()中首先获取目标Activity所在的进程,设置活动的启动时间,然后判断进程是否启动,对于已经启动的进程执行realStartActivityLocked()创建Activity实例,对于未启动的进程调用startProcessLocked()启动进程;

  • realStartActivityLocked():进程已启动的情况下,直接创建Activity实例完成DecorView相关初始化
 mService.mWindowManager.setAppVisibility(r, true);
r.app = app; // 赋值进程信息
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
        System.identityHashCode(r), r.info,
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
        profilerInfo));
mService.getLifecycleManager().scheduleTransaction(clientTransaction); // 执行ActivityThread中方法启动Activity

app.thread.scheduleLaunchActivity(new Intent(r.intent), r,  // 执行scheduleLaunchActivity()启动活动,参见四大组件的启动过程

在realStartActivityLocked中完成创建Activity实例和DecorView相关初始化,具体信息查看Android四大组件启动过程;

2.3 处理进程未启动

对于应用进程未启动的执行startProcessLocked()启动相应进程,关于程序的进程启动参见(应用程序的进程启动)进程启动后进入ActivityThread.main()中,在main()中会调用attach()方法,然后调用AMS.attachApplication()中

final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid); // 获取客户端进程的pid,调用attachApplicationLocked()通知启动完成
  • attachApplicationLocked()
ProcessRecord app = mPidsSelfLocked.get(pid); // 1、
String processName = app.processName; // 获取进程名称
thread.asBinder().linkToDeath(new AppDeathRecipient(app, pid, thread), 0); // 设置Binder的死亡监听
app.thread = thread; // 赋值AMS中持有的thread
thread.bindApplication(processName, app.instrumentationInfo != null // 2、
           ? app.instrumentationInfo : app.info, providers,
           app.instrumentationClass, app.instrumentationProfileFile,
           app.instrumentationArguments, app.instrumentationWatcher, testMode,
           isRestrictedBackupMode || !normalMode,
           mConfiguration, getCommonServicesLocked());
if (mStackSupervisor.attachApplicationLocked(app)) { // 调用ActivitySupervisor方法
}
final ActivityRecord top = stack.topRunningActivityLocked(); // 3、
if (activity.app == null && app.uid == activity.info.applicationInfo.uid
        && processName.equals(activity.processName)) {
    try {
        if (realStartActivityLocked(activity, app,  // 4、
                top == activity /* andResume */, true /* checkConfig */)) {
            didSomething = true;
        }
    } 
}. 

在attachApplication()中,

  1. 首先根据pid获取进程信息ProcessRecord对象,然后为启动的进程设置死亡监听
  2. 回调bindApplication(),执行handleBindApplication()
  3. 获取stack顶部的ActivityRecord,判断是否等待启动,此时是获取到栈顶的活动正式要启动的Activity
  4. 执行realStartActivityLocked完成启动Activity

总结:AMS在接收到启动请求时,会先使用PMS找到最佳处理的活动,然后根据请求设置的Flag和活动中设置的Mode确定是否可重用活动,如果可重用处理其Task栈的相关信息并将ActivityRecord放置在栈顶,然后执行当前可交互Activity的Pause操作,执行结束后回调AMS方法,AMS取出要启动的活动执行Resume操作,对于未匹配重用的,首先判断进程是否启动,若未启动先启动进程,启动完成后重新创建Activity对象,实现活动的启动;

你可能感兴趣的:(Android,Framework)