Activity启动(3)----Task,Activity,Process的管理

    ActivityManagerService管理着Activity,Task和应用程序进程。三者在AMS中的表现形式分别为:ActivityRecord,TaskRecord,ProcessRecord。这三者的关系如下图所示:

从图中可以看出,AMS是按层次关系进行管理所有的Activity的。
(1) ActivityStackSupervisor的成员mStacks是AMS管理层次的顶层,类型为ArrayList<ActivityStack>,它只包含两个stack: mHomeStack和mFocusedStack。mHomeStack保存Luncher App的Task(activity), mFocusedStack保存非Laucher App的Task(activity)。
(2) mHomeStack和mFocusedStack的类型是ActivityStack,它有一个ArrayList<TaskRecord>类型的成员mTaskHistory,用于存储TaskRecord。
(3) TaskRecord有一个类型为ArrayList<ActivityRecord>的成员mActivities,用于保存属于该Task的所有Activity。类型为ActivityStack的成员stack,记录所属的栈。numActivities记录当前Task中Activity的数量。
(4) 每个ActivityRecord会对应到一个TaskRecord,ActivityRecord中类型为TaskRecord的成员task,记录所属的Task。
(5) AMS通过辅助类ActivityStackSupervisor来操作Task, 通过ActivityStack操作Activity。想找到某个Activity,需要按层次查找:先找到对应的栈, 再找到栈中的Task,再在该Task中查找Activity
(6) 同一个TaskRecord的Activity可以分别处于不同的进程中,每个Activity所处的进程跟所处的Task没有关系。

 1. 创建ActivityRecord

startActivityLocked()@ActivityStackSupervisor.java

final int startActivityLocked(IApplicationThread caller,    // caller是请求启动当前Activity的应用方,IApplicationThread类是AMS调用ActivityThread的IBinder接口。
                              Intent intent, String resolvedType, ActivityInfo aInfo,
                              IBinder resultTo,       // 调用方Activity的ActivityRecord,每个Activity在启动之后,AMS均会将这个Activity的ActivityRecord的IBinder再传递给Activity,作为其在AMS中的标识。
                              String resultWho, int requestCode,
                              int callingPid, int callingUid,  // 用于权限检查,检查请求方是否有权限启动这个Activity.
                              String callingPackage, int startFlags, Bundle options,
                              boolean componentSpecified, ActivityRecord[] outActivity) {
    int err = ActivityManager.START_SUCCESS;
    
    ProcessRecord callerApp = null;
    if (caller != null) {       // caller不为空,callingPid和callingUid为caller activity所在进程的PID和UID。若caller为空,则为请求启动Activity的进程的PID和UID。
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }

    ActivityRecord sourceRecord = null;           // 表示请求启动当前activity的activity.
    ActivityRecord resultRecord = null;           // 表示当前activity启动之后需要得到返回结果的activity。
    if (resultTo != null) {
        sourceRecord = isInAnyStackLocked(resultTo);
        if (sourceRecord != null) {       // 一般情况下,sourceRecord的activity使用startActivityForResult()启动当前activity且requestCode>=0,那么resultRecord = sourceRecord。
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }

    ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;

    int launchFlags = intent.getFlags();
        // 特殊情况,若sourceRecord启动当前activity时设置了标记Intent.FLAG_ACTIVITY_FORWARD_RESULT,且requestCode<0, 那么当前activity的resultRecord等于sourceRecord.resultTo,也就是sourceRecord的resultRecord。
    if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        // 将sourceRecord的resultRecord转移给当前新启动的activity.
        if (requestCode >= 0) {
            ActivityOptions.abort(options);
            return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
        }
        resultRecord = sourceRecord.resultTo;
        resultWho = sourceRecord.resultWho;
        requestCode = sourceRecord.requestCode;
        sourceRecord.resultTo = null;
        if (resultRecord != null) {
            resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
        }
    }
    
    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) {
        if (resultRecord != null) {     // 启动新activity出错,发送result给resultRecord。
            resultStack.sendActivityResultLocked(-1,
                    resultRecord, resultWho, requestCode,
                    Activity.RESULT_CANCELED, null);
        }
        setDismissKeyguard(false);
        ActivityOptions.abort(options);
        return err;
    }
    // 检查启动权限
    final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, callingUid);
    final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, callingUid, aInfo.applicationInfo.uid, aInfo.exported);
    if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(-1,
                        resultRecord, resultWho, requestCode,
                        Activity.RESULT_CANCELED, null);
        }
        setDismissKeyguard(false);
        String msg;
        if (!aInfo.exported) {
            msg = "Permission Denial: starting " + intent.toString()
                            + " from " + callerApp + " (pid=" + callingPid
                            + ", uid=" + callingUid + ")"
                            + " not exported from uid " + aInfo.applicationInfo.uid;
        } else {
            msg = "Permission Denial: starting " + intent.toString()
                            + " from " + callerApp + " (pid=" + callingPid
                            + ", uid=" + callingUid + ")"
                            + " requires " + aInfo.permission;
        }
        throw new SecurityException(msg);
    }
    
    // IntentFirewall.checkStartActivity()函数检查一个start activity的intent是否允许。
    boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                                 callingPid, resolvedType, aInfo.applicationInfo);

    if (mService.mController != null) {
        // 判断这个activity是否正在启动。
        try {
            Intent watchIntent = intent.cloneFilter();
            abort |= !mService.mController.activityStarting(watchIntent, aInfo.applicationInfo.packageName);
        } catch (RemoteException e) {
            mService.mController = null;
        }
    }
    
    // intent不允许或者被请求的activity正在启动,则中止本次启动请求。
    if (abort) {
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                            Activity.RESULT_CANCELED, null);
        }
       // 假装告诉caller是真正开始了,但它将只得到一个取消的结果。
        setDismissKeyguard(false);
        ActivityOptions.abort(options);
        return ActivityManager.START_SUCCESS;
    }
    
    // 创建ActivityRecord
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                                          intent, resolvedType, aInfo, mService.mConfiguration,
                                          resultRecord, resultWho, requestCode, componentSpecified, this);
    if (outActivity != null) {
        outActivity[0] = r;       // 将创建的ActivityRecord返回
    }
    
    final ActivityStack stack = getFocusedStack();
    if (stack.mResumedActivity == null || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
        if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
            PendingActivityLaunch pal = new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
            mService.mPendingActivityLaunches.add(pal);
            setDismissKeyguard(false);
            ActivityOptions.abort(options);
            return ActivityManager.START_SWITCHES_CANCELED;
        }
    }
    ......    
    mService.doPendingActivityLaunchesLocked(false);

    err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
    ......
    return err;
}

1.1 Permission检查

checkPermission()@ActivityManagerService.java

public int checkPermission(String permission, int pid, int uid) {
    if (permission == null) {
        return PackageManager.PERMISSION_DENIED;
    }
    return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
}

checkComponentPermission()@ActivityManagerService.java

int checkComponentPermission(String permission, int pid, int uid, int owningUid, boolean exported) {

    Identity tlsIdentity = sCallerIdentity.get();
    if (tlsIdentity != null) {
         uid = tlsIdentity.uid;
         pid = tlsIdentity.pid;
    }

    if (pid == MY_PID) {  // 在自己所在进程(own process), 则授权
        return PackageManager.PERMISSION_GRANTED;
    }

    return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported);
}

checkComponentPermission()@ActivityManager.java

public static int checkComponentPermission(String permission, int uid, int owningUid, boolean exported) {
    // Root uid(0), system server uid(Process.SYSTEM_UID)授权permission.
    if (uid == 0 || uid == Process.SYSTEM_UID) {
        return PackageManager.PERMISSION_GRANTED;
    }

    // Isolated processes不授权.
    if (UserHandle.isIsolated(uid)) {
        return PackageManager.PERMISSION_DENIED;
    }

    // 如果一个uid拥有被访问的所有东西,无论它请求什么permissions,它都可以完全访问它们,即被授权。
    if (owningUid >= 0 && UserHandle.isSameApp(uid, owningUid)) {
        return PackageManager.PERMISSION_GRANTED;
    }

    // 如果被请求启动的activity属性android:exported=false, 则不授权。
    if (!exported) {
        return PackageManager.PERMISSION_DENIED;
    }

    // 如果被请求启动的activity的permission为空,则授权。
    if (permission == null) {
        return PackageManager.PERMISSION_GRANTED;
    }
    
    // 被请求启动的activity设定了permission,那么检查请求方的activity中是否声明了使用这个permission,如果声明,授权。
    try {
        return AppGlobals.getPackageManager().checkUidPermission(permission, uid);
    } 

    return PackageManager.PERMISSION_DENIED;
}

 

2. Task的创建与管理

2.1 Task与Application的区别

Application可以看成是在Android开发中的一个容器,用于存放和组织一个应用程序的activity,这些activity与Application之间是静态关系,并且是一一对应的,也就是说activity在PackManager中的最终形式是唯一的,并且只对应一个Application。而Task和activity之间是动态关系,是运行应用程序时,activity的调用栈,同一个Task中的activity可能来自不同的Application。

2.2 startActivityUncheckedLocked()

    ActivityStackSupervisor.startActivityLocked()函数在创建了ActivityRecord之后,调用了startActivityUncheckedLocked,处理Task相关的内容就是在这个函数里。
startActivityUncheckedLocked()@ActivityStackSupervisor.java

final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
                                       int startFlags, boolean doResume, Bundle options) {
    final Intent intent = r.intent;
    final int callingUid = r.launchedFromUid;
    
    int launchFlags = intent.getFlags();
    
    // 只有正在启动的activity没明确声明这是自动启动时,在onPause()调用之前才会调用onUserLeaving()。
    mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
    
    // 如果caller要求现在这个点不要resume, 在record里记录下来,在寻找top running activity的时候调过它。
    if (!doResume) {
        r.delayedResume = true;
    }
    
    ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;

    // 如果设置了onlyIfNeeded,如果正在被启动的activity与调用方一样,可以这样做,或者作为一种特殊情况,如果不知道caller是谁,把当前top activity作为caller。
    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
        ActivityRecord checkedCaller = sourceRecord;
        if (checkedCaller == null) {
            checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
        }
        if (!checkedCaller.realActivity.equals(r.realActivity)) {
            // caller不是launcher, 通常需要这个标志。
            startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
        }
    }
    //需要创建新task的情况
    if (sourceRecord == null) {
        // activity不是由另外一个activity启动的,这种情况下通常需要开启一个新的task.
        if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        }
    } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        // 如果原始activity(sourceRecord)以single instance方式运行,那它请求启动的activity必须运行在它自己的task里。
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
        // 如果被请求启动的activity的launchMaode是LAUNCH_SINGLE_INSTANCE或者LAUNCH_SINGLE_TASK,那么它通常在它自己的task里启动。
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    }

    final ActivityStack sourceStack;
    if (sourceRecord != null) {
        if (sourceRecord.finishing) {
            // 如果source activity正在finishing, 不能把它当作被启动activity的source, 因为source关联的那个task现在可能为空并正在退出,因此不能盲目地把将要启动的activity放到那个task里,而是走NEW_TASK的路径去为它找到一个task。
            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
            }
            sourceRecord = null;
            sourceStack = null;
        } else {
            sourceStack = sourceRecord.task.stack;
        }
    } else {
        sourceStack = null;
    }

    // 若设置了FLAG_ACTIVITY_NEW_TASK, 新的activity是通过startActivityForResult()请求启动的,并且requestCode >=0,则断开与caller的依赖。
    if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        // 新的activity不管哪种原因需要在新task里启动,但是caller却要求得到返回结果。这会引起混乱,因此立即返回一个取消的结果,让新的task不依赖于它的source而继续正常的启动。
        r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, r.requestCode, Activity.RESULT_CANCELED, null);
        r.resultTo = null;
    }

    boolean addingToTask = false;
    boolean movedHome = false;
    TaskRecord reuseTask = null;
    ActivityStack targetStack;
    if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
                    (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
                    || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
                    || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        // 如果被要求到前台,不要求返回结果,而且可以找到一个使用相同组件启动的task, 那么将它移到前台。
        if (r.resultTo == null) {
            // 看看是否有一个task可以带到前台。如果这是SINGLE_INSTANCE的activity, 在history里它可能有而且只有一个实例,而且在它独占的task里,因此查找一下。
            ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
                            ? findTaskLocked(r)
                            : findActivityLocked(intent, r.info);
            if (intentActivity != null) {
                if (r.task == null) {
                    r.task = intentActivity.task;
                }
                targetStack = intentActivity.task.stack;
                targetStack.mLastPausedActivity = null;
                moveHomeStack(targetStack.isHomeStack());
                if (intentActivity.task.intent == null) {
                    // 如果task的启动是由于activity基于affinity的活动,现在就真正去启动它,并指定基本的intent。
                    intentActivity.task.setIntent(intent, r.info);
                }

                // 如果目标task不在前台,那么需要把它移到前台,但是因为SINGLE_TASK_LAUNCH,它并不完全清楚该怎么做。我们希望有相同的行为,就像启动一个新的实例一样,这意味着如果caller自己不在前台,那就不将它移到前台。
                // 因为要复用task, 因此将taskTop所在的task移至前台。
final ActivityStack lastStack = getLastStack(); ActivityRecord curTop = lastStack == null? null : lastStack.topRunningNonDelayedActivityLocked(notTop); if (curTop != null && (curTop.task != intentActivity.task || curTop.task != lastStack.topTask())) { r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); if (sourceRecord == null || (sourceStack.topActivity() != null && sourceStack.topActivity().task == sourceRecord.task)) { // 希望马上将activity展示在用户面前。 movedHome = true; if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {                             // caller想出现在home activity. intentActivity.task.mOnTopOfHome = true; } targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); options = null; } } // 如果caller要求目标task reset,那就照做。
                // Reset Task。
if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); }
if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { // 不需要启动一个新的activity,如果是这样的话client要求不做任何事,那么就是它了。确保top activity正确resumed。 if (doResume) { resumeTopActivitiesLocked(targetStack, null, options); } else { ActivityOptions.abort(options); } return ActivityManager.START_RETURN_INTENT_TO_CALLER; } if ((launchFlags & (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { // caller要求使用新activity完全替换已经存在的task,这个工作不应该困难。 reuseTask = intentActivity.task; reuseTask.performClearTaskLocked(); reuseTask.setIntent(r.intent, r.info); } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { // 这种情况下,task移除要启动的activity以上的所有activity。在大多数情况下,这意味着重置task到其初始状态。 ActivityRecord top = intentActivity.task.performClearTaskLocked(r, launchFlags); if (top != null) { if (top.frontOfTask) { // activity别名可能意味着top activity使用不同的intents,那么确保task现在有新intent的特性。 top.task.setIntent(r.intent, r.info); } ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); top.deliverNewIntentLocked(callingUid, r.intent); } else { // 一种特殊情况:因为这个activity不是当前正在运行的, 所以需要去启动它,而且caller已经要求清除当前的task,好让这个activity在顶部。 addingToTask = true; // 现在可以当作activity是由它的task的顶部启动的,因此它在正确的地方了。 sourceRecord = intentActivity; } } else if (r.realActivity.equals(intentActivity.task.realActivity)) { // 在这中情况下,task中的top activity与被启动的activity是相同的,因此我们把这项工作的要求看作是要把task移到前台。若task的top activity是root activity, 如果它要求就将新的intent传递给它。 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) && intentActivity.realActivity.equals(r.realActivity)) { ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, intentActivity.task); if (intentActivity.frontOfTask) { intentActivity.task.setIntent(r.intent, r.info); } intentActivity.deliverNewIntentLocked(callingUid, r.intent); } else if (!r.intent.filterEquals(intentActivity.task.intent)) { // 这种情况下,启动task的root activity, 使用不容的intent。应该在top启动一个新的实例。 addingToTask = true; sourceRecord = intentActivity; } } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { // 这种情况下,启动activity到一个已存在的task里,这个task没有reset。这通常是从notification或者快捷方式启动activity的情况。我们希望将新的activity放置在当前task的top。 addingToTask = true; sourceRecord = intentActivity; } else if (!intentActivity.task.rootWasReset) { // 在这种情况下,启动activity到一个已存在的task里,这个task还没有从它的前门启动。当前task已经被移至前台。理想情况下,我们可能希望将新的task放到它的stack的底部,但目前的代码组织实现这个比较困难,因此放弃这种做法。 intentActivity.task.setIntent(r.intent, r.info); } if (!addingToTask && reuseTask == null) { // 不做任何事情,但这步是必要的(client没有使用intent),确保top activity正确地resume。 if (doResume) { targetStack.resumeTopActivityLocked(null, options); } else { ActivityOptions.abort(options); } return ActivityManager.START_TASK_TO_FRONT; } } } } if (r.packageName != null) { // 如果正在启动的activity与当前top的activity相同,那么需要检查它是否应该只被启动一次。 ActivityStack topStack = getFocusedStack(); ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); if (top != null && r.resultTo == null) { if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { if (top.app != null && top.app.thread != null) { if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task); // 确保top activity正确地resume。 topStack.mLastPausedActivity = null; if (doResume) { resumeTopActivitiesLocked(); } ActivityOptions.abort(options); if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { // 不需要启动一个新的activity,client不做任何事,如果是这样的话,那这就是它。 return ActivityManager.START_RETURN_INTENT_TO_CALLER; } top.deliverNewIntentLocked(callingUid, r.intent); return ActivityManager.START_DELIVERED_TO_TOP; } } } } } else { if (r.resultTo != null) { r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, r.requestCode, Activity.RESULT_CANCELED, null); } ActivityOptions.abort(options); return ActivityManager.START_CLASS_NOT_FOUND; } boolean newTask = false; boolean keepCurTransition = false; // 这是否应该算是一个新的task ? if (r.resultTo == null && !addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { targetStack = adjustStackFocus(r); moveHomeStack(targetStack.isHomeStack()); if (reuseTask == null) { r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), null, true);  // 在新的task中启动新的activity         } else { r.setTask(reuseTask, reuseTask, true); } newTask = true; if (!movedHome) { if ((launchFlags & (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {                 // caller想要在home activity中出现,那么在开始它们自己的activity之前将home移至前台。 r.task.mOnTopOfHome = true; } } } else if (sourceRecord != null) { TaskRecord sourceTask = sourceRecord.task; targetStack = sourceTask.stack; moveHomeStack(targetStack.isHomeStack()); if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { // 这种情况下,将activity加入到一个存在的task中,但是如果activity已经运行的话,caller要求清除task。 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); keepCurTransition = true; if (top != null) { ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); top.deliverNewIntentLocked(callingUid, r.intent); // 确保top activity正确地resume。 targetStack.mLastPausedActivity = null; if (doResume) { targetStack.resumeTopActivityLocked(null); } ActivityOptions.abort(options); return ActivityManager.START_DELIVERED_TO_TOP; } } else if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { // 这种情况下,在自己的task中启动activity, 这个activity可能以前在某个地方运行过,如果这样的话,将它移到stack的前面。 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); if (top != null) { final TaskRecord task = top.task; task.moveActivityToFrontLocked(top); ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); top.updateOptionsLocked(options); top.deliverNewIntentLocked(callingUid, r.intent); targetStack.mLastPausedActivity = null; if (doResume) { targetStack.resumeTopActivityLocked(null); } return ActivityManager.START_DELIVERED_TO_TOP; } } // 一个已存在的activity正在启动这个新的activity, 新的activity与启动它的activity在同一个task里。 r.setTask(sourceTask, sourceRecord.thumbHolder, false); } else { // 不是从一个已存在的activity启动,也不是一个新的task的一部分,就把它放到top task,虽然这种情况不应该发生。 targetStack = adjustStackFocus(r); moveHomeStack(targetStack.isHomeStack()); ActivityRecord prev = targetStack.topActivity(); r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), null, true); } mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, intent, r.getUriPermissionsLocked()); if (newTask) { EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); } ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); targetStack.mLastPausedActivity = null; targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); mService.setFocusedActivityLocked(r); return ActivityManager.START_SUCCESS; }

    这个函数涉及的内容很繁杂,在这里对部分内容做一些解析。

2.3 Intent flag介绍

Intent携带的flag对于task的影响很大,这里简单介绍下上面函数中用到的flag。

(1) Intent.FLAG_ACTIVITY_NO_USER_ACTION

     如果设置了这个flag, 在新启动的activity被移到前台,当前最前面的activity被paused之前,将会阻止回调onUserLeaveHint(),可以在避免用户离开当前Activity时回调到 onUserLeaveHint(). 通常,Activity可以通过这个回调表明有明确的用户行为导致当前activity切出前台。 这个回调标记了activity生命周期中的一个恰当的点,可以“在用户看过通知之后”将通知清除,如闪烁LED灯。
     如果Activity是由非用户驱动的事件(如电话呼入或闹钟响铃)启动的,那这个标志就应该被传入Context.startActivity,以确保被打断的activity不会认为用户已经看过通知。

(2) Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP

     如果设置了这个flag,而且这个intent被用于从已有activity启动另外一个新的activity, 那么当前的activity不会被当成top activity用来决定是否传送这个新intent给top activity而不是启动一个新的activity。当前activity的前一个的activity会被当作top activity,假定当前的Acitvity会立即把自己finish掉。

    例如A-->B-->C,若B启动C时设置了这个标志位,那在启动时B并不会被当作top activity,而是用A做top来启动C。
    典型的场景是在应用选择页面,如果在文本中点击一个网址要跳转到浏览器,而系统中又装了不止一个浏览器应用,此时会弹出应用选择页面。在应用选择页面选择某一款浏览器启动时,就会用到这个Flag。然后应用选择页面将自己finish,以保证从浏览器返回时不会在回到选择页面。

(3) Intent.FLAG_ACTIVITY_NEW_TASK

    如果设置了这个flag, 这个activity将会成为一个新task历史栈的开始。一个task(从启动它的activity到task中的下一个activity)定义了用户可以跳转的原子的activities群。Tasks可以在前台和后台之间切换;一个特定task中的所有activities会一直保持同样的顺序。
    这个flag通常被activity用来展示一种"launcher"类型的行为:为用户提供能够完成的独立事件列表,这些事件的运行完全独立于启动它们的activity。
    当使用这个activity时,如果一个task已经运行了你要启动的activity,那么就不会启动一个新的activity,而是将现有task以现有状态直接切换至前台。
    这个flag不能在caller请求要启动的activity返回结果时使用。
    注意:假设A启动B,如果要让B在新的task中创建,那么要求这两个Activity的taskAffinity不能相同。也就是说,设置了这个标志后,新启动的activity并非就一定在新的task中创建,如果A和B在属于同一个package,而且都是使用默认的taskAffinity,那B还是会在A的task中被创建。 所以,只有A和B的taskAffinity不同时,设置了这个标志才会使B被创建到新的task。

(4) Intent.FLAG_ACTIVITY_MULTIPLE_TASK

    除非你要实现自己的顶级的应用启动器,否则不要用这个flag。与FLAG_ACTIVITY_NEW_TASK联合使用,禁止将已有的task移到前台。当设置了,总会为这个intent启动一个新的task作为activity的宿主,而不管是否已经存在运行同样事情的task.因为系统默认不包含task的图形化管理,除非你为用户提供返回到已启动task的方法,否则不要用这个flag。
    如果没有设置FLAG_ACTIVITY_NEW_TASK,那么这个flag也被忽视。

(5) Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT

    通常在应用代码中不需要设置这个flag,当launchMode为singleTask时系统会默认设置这个flag。

(6) Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

    如果设置了这个flag, 这个activity正在一个新的task中启动或者正在从一个已存在的task中移到top,那么它被当作这个task的前门来启动。这会导致需要任何affinities的应用程序保证那个task处于适当的状态下(不管activity是移进还是移出),或者如果必要的话简单地重置task至初始状态。

(7) Intent.FLAG_ACTIVITY_CLEAR_TASK

    如果设置了这个flag, 会导致包含已存在待启动的activity的task在该activity启动前被清空。即,该activity会成为一个空task的新的root,而且其它旧的activities都被finish掉。这个flag只能与FLAG_ACTIVITY_NEW_TASK一起使用。

(8) Intent.FLAG_ACTIVITY_CLEAR_TOP

    如果设置了这个flag,被启动的activity已经存在于当前task中,那么不会为这个activity启动一个新的实例,这个将task中这个activity之上的其它activity都关闭掉,这个intent被当作新的intent传给这个旧的activity(当前已在top)。
    例如,一个task中包含4个activity,从栈底到栈顶顺序为:A,B,C,D。如果D调用startActivity()启动B,那么C和D将会被finished掉,并且B收到这个intent,结果是现在task栈为:A,B。
    上面例子中正在运行的实例B,既可以在onNewIntent函数中接收新的intent,也可以先自己finish掉自己,然后用新的intent重新启动。如果activity声明了它的launch mode为“multiple”(默认值),而且intent中没有设置Intent.FLAG_ACTIVITY_SINGLE_TOP, 那么它将会被finish掉然后重新创建。对于其它的launch mode或者设置了Intent.FLAG_ACTIVITY_SINGLE_TOP,那么这个intent将会被传给当前activity实例的onNewIntent()。
    注意:这种启动模式可以与FLAG_ACTIVITY_NEW_TASK一起使用:如果用来启动一个task的root activity,它会将这个任务中现在运行的实例调到前台,然后将任务清空至只有root activity的状态。例如要从通知中心里启动一个Activity时。

(9) Intent.FLAG_ACTIVITY_SINGLE_TOP 

    如果设置了这个标记,若被启动的activity已经在栈顶运行,那么它不会被再次启动。

(10) Intent.FLAG_ACTIVITY_TASK_ON_HOME

    如果设置了这个flag, 这个flag将会导致新启动的task被置于当前home activity task之上(如果有的话),也就是说,在这个task中按返回键时,总是回退到home界面,即使home不是用户最后看到的界面。这个flag只能与Intent.FLAG_ACTIVITY_NEW_TASK一起使用。
    例如,A-->B-->C-->D,如果C启动D时设置了这个flag, 那么在D中按返回键时就会直接返回到桌面,而不是返回到C。注意,只有D是在新的task中被创建时(即D的launch mode是singleInstance时,或者是D指定了与C不懂的taskAffinity并设置了FLAG_ACTIVITY_NEW_TASK时),使用Intent.FLAG_ACTIVITY_TASK_ON_HOME才有效。

(11) Intent.FLAG_ACTIVITY_REORDER_TO_FRONT

    如果设置了这个flag, 如果被启动的activity已经运行,那么这个已启动的activity将被移至task的栈顶。
    例如,一个task中包含4个activity,从栈底到栈顶顺序为:A,B,C,D。如果D调用startActivity()启动B时使用了这个flag,那么B将会被调节到栈顶,结果顺序:A,C,D,B。否则,顺序会是:A,B,C,D,B。
    若设置了Intent.FLAG_ACTIVITY_CLEAR_TOP,那么这个flage将会被忽视。

2.4 launchMode介绍

ActivityInfo.LAUNCH_MULTIPLE  : standard

ActivityInfo.LAUNCH_SINGLE_TOP : singleTop

ActivityInfo.LAUNCH_SINGLE_TASK : singleTask

ActivityInfo.LAUNCH_SINGLE_INSTANCE : singleInstance

分两种情况讨论下这四种launchMode :

(1) 一个task的情况:

standard :不管当前task是否存在要启动的activity,都会创建一个新的activity。比如task为A B,这时要启动B,那么task将变为A B B。

singleTop :如果要启动的activity就在task的top, 那么不会创建新的activity, 只会调用onNewIntent()。如果不在top(或者task中没有该activity),那么就会创建新的activity。例如task为A B,这时若启动B,则task仍为A B;若启动A,

                  那么task将变为A B A。

singleTask :如果当前task中存在要启动的activity, 那么不会创建新的activity,会将该activity上面的activity移除并将该activity移至top;如果不存在,则会创建新的activity,如task为A B C,启动B,那么task将变为A B。

singleInstance : 具有该mode的activity独占一个task,不允许加入其它task。

(2) 多个task的情况

standard :如果要启动的activity在后台task中,那么不管这个activity在后台task是否存在,都会创建一个新的activity,并将它加入到前台的task中去。

singleTop :如果要启动的activity在后台task中,且这个activity在后台task的top,这时需要结合Intent.FLAG_ACTIVITY_NEW_TASK进行判断。

                 若启动activity的intent设置了这个flag,那么将会把后台task移至前台,例如前台task为A B,后台task为C E F,现在前台task需要启动一个F,intent设置了FLAG_ACTIVITY_NEW_TASK,那么后台task将被移至前台,并调用F

                 的onNewIntent(),A B所在的task变为后台task;若没设置该flag,那就在前台task中新创建一个activity F。

                 singleTask :如果要启动的activity在后台task中, 那么不管该activity是否在top,都会将后台task移至前台,前台task移至后台。不需要考虑flag,因为要启动的activity如果是singleTask,那么自动在启动activity的intent中加上

                 FLAG_ACTIVITY_NEW_TASK。

singleInstance : 如果要启动的activity在后台task中,那么会调用该activity的onNewIntent,并且后台task仍然在后台。如果后台task中没有该activity,那么会重新创建一个activity,并单独放入一个task中,其实在启动的intent中也会加上

                FLAG_ACTIVITY_NEW_TASK。

(3) taskAffinity属性介绍

 

2.5 需要创建新的task的情况

(1) 如果sourceRecord为null(从Launcher启动一个Activity或者通过Context启动一个Activity时sourceRecord为null)。

(2) 如果sourceRecord的launchMode设置的是singleinstance,那么在Intent添加 FLAG_ACTIVITY_NEW_TASK,因为对于singleinstance的activity,是不会与其它activity共享一个 task的。

(3) 如果被启动的activity的launchMode是singleinstance或者singletask,那么也会在Intent中添加FLAG_ACTIVITY_NEW_TASK。

2.6 Task复用

2.6.1 Task的基本属性

(1) task的root activity是指启动一个activity时新创建一个新的task,则这个activity就是这个task的activity。

(2) task.affinity是指root activity的affinity。

(3) task.intent是指启动root activity的intent。

(4) task.affinityIntent是指activity在进行了TaskReparenting操作后,AMS为activity分配新的task,这个新的task的affinityIntent则是启动该activity的Intent,此时task.intent为null。

     TaskReparenting操作示例:假设有A,B两个activity,它们拥有不同的affinity,而且从activity A中启动activity B, 假设A是所在task的root activity,如图所示:

    

    假设activity B设置了ActivityInfo.FLAG_ALLOW_TASK_REPARENTING, 如果此时另外一个applicationy要求启动activity B并要求它在新的task中,那么activity B将被从task A中移到新的task中,如图所示:    

           

 2.6.2 查找可复用的Task

 2.6.2.1 需要查找可复用task的条件

(1) (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0
    如果设置了Intent.FLAG_ACTIVITY_MULTIPLE_TASK,那么不管是否有可复用的task,都会去启动一个新的task。因此,若没有设置Intent.FLAG_ACTIVITY_MULTIPLE_TASK,但设置了Intent.FLAG_ACTIVITY_NEW_TASK,那么就需要查找是否存在可复用的task。

(2) r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK

(3) r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE

 2.6.2.2 查找可复用task的规则

(1) launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE的情况

findTaskLocked()@ActivityStackSupervisor.java

ActivityRecord findTaskLocked(ActivityRecord r) {
    for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
        final ActivityStack stack = mStacks.get(stackNdx);
        if (!r.isApplicationActivity() && !stack.isHomeStack()) {
            continue;
        }
        final ActivityRecord ar = stack.findTaskLocked(r);
        if (ar != null) {
            return ar;
        }
    }
    return null;
}

 findTaskLocked()@ActivityStack.java

// 返回任何已存在与给定intent匹配的的task中的top activity,若没有这样的task,则返回null。
ActivityRecord findTaskLocked(ActivityRecord target) {
    Intent intent = target.intent;
    ActivityInfo info = target.info;
    ComponentName cls = intent.getComponent();
    if (info.targetActivity != null) {
        cls = new ComponentName(info.packageName, info.targetActivity);
    }
    final int userId = UserHandle.getUserId(info.applicationInfo.uid);

    for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
        final TaskRecord task = mTaskHistory.get(taskNdx);
        if (task.userId != userId) {
            // 忽略不同user的task。
            continue;
        }
        final ActivityRecord r = task.getTopActivity();
        if (r == null || r.finishing || r.userId != userId || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
            // task的root activity不匹配忽略。
            continue;
        }

        if (task.affinity != null) {          //task.affinity不为空,若task的affinity与要启动的activity的affinity相同,即root activity的affinity与要启动的activity的affinity相同,那么就找到了可复用的task。
            if (task.affinity.equals(info.taskAffinity)) {
                // 找到匹配的affinity。
                return r;
            }
        } else if (task.intent != null && task.intent.getComponent().equals(cls)) { // task.affinity为空,即android:taskAffinity被设置为""。此时判断task的root activity与启动的activity是否相同。
            // 找到匹配的class    
            return r;
        } else if (task.affinityIntent != null && task.affinityIntent.getComponent().equals(cls)) {
            // task.intent为空,task.affinityIntent不为空,这种情况发生在TaskReparenting之后。
            // 此时需要通过task.affinityIntent.getComponent()与要启动的activity的Component比较,看是否与启动的activity相同。
// 找到匹配的class return r; } else if (DEBUG_TASKS) { // 没有找到匹配的task。 Slog.d(TAG, "Not a match: " + task); } } return null; }

该函数返回的均是找到的task中最上面的activity,而不一定是task的root activity,至于如何处理要启动的activity和task中已有的activity,后面会继续介绍。

(2) launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE的情况

findActivityLocked()@ActivityStackSupervisor.java

ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
    for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
        final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
        if (ar != null) {
            return ar;
        }
    }
    return null;
}

findActivityLocked()@ActivityStack.java

// 返回从stack的top启动的第一个activity,这个activity与给定的activity一样。若没找到这样的activity,则返回null。
ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
    ComponentName cls = intent.getComponent();
    if (info.targetActivity != null) {
        cls = new ComponentName(info.packageName, info.targetActivity);
    }
    final int userId = UserHandle.getUserId(info.applicationInfo.uid);

    for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
        TaskRecord task = mTaskHistory.get(taskNdx);
        if (task.userId != mCurrentUser) {
            return null;
        }
        final ArrayList<ActivityRecord> activities = task.mActivities;
        for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
            ActivityRecord r = activities.get(activityNdx);
            if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) {
                // 找到匹配的class
                return r;
            }
        }
    }
    return null;
}

2.6.3 将task移到mTaskHistory顶部

    上面得到的是ActivityRecord intentActivity,接下来将intentActivity所在的task移到mTaskHistory的前端。

moveTaskToFrontLocked()@ActivityStack.java

final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) {
    final int numTasks = mTaskHistory.size();
    final int index = mTaskHistory.indexOf(tr);
    if (numTasks == 0 || index < 0)  {
        // 什么也不做
        if (reason != null && (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
            ActivityOptions.abort(options);
        } else {
            updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
        }
        return;
    }

    mStackSupervisor.moveHomeStack(isHomeStack());
    
    // 将task中所有的activities转移到stack的顶部,使它们保持相同的内部顺序。 insertTaskAtTop(tr); if (reason != null && (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); ActivityRecord r = topRunningActivityLocked(null); if (r != null) { mNoAnimActivities.add(r); } ActivityOptions.abort(options); } else { updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options); } mWindowManager.moveTaskToTop(tr.taskId); mStackSupervisor.resumeTopActivitiesLocked(); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } }

insertTaskAtTop()@ActivityStack.java

private void insertTaskAtTop(TaskRecord task) {
    // 如果这是由另外一个activity或者从home activity启动引发的移至top的动作,那么设置响应的mOnTopOfHome。
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    final boolean fromHome = lastStack == null ? true : lastStack.isHomeStack();
    if (!isHomeStack() && (fromHome || topTask() != task)) {
        task.mOnTopOfHome = fromHome;
    }

    mTaskHistory.remove(task);

    // 将task放到顶部
    int stackNdx = mTaskHistory.size();
    if (task.userId != mCurrentUser) {
        // 将非当前用户tasks放到当前用户task的下面。
        while (--stackNdx >= 0) {
            if (mTaskHistory.get(stackNdx).userId != mCurrentUser) {
                break;
            }
        }
        ++stackNdx;
    }
    mTaskHistory.add(stackNdx, task);
}

2.6.4 Reset Task

       如果Intent设置Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,最常见的情况,当从Home启动应用程序时,会设置这个flag;从当前task进入应用程序时,则不会设置这个falg。若设置了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,AMS会对复用的task作一些处理。

activity的几个关键处理属性:

      ① 如果复用task在后台时间超过30min,那么将删除除root activity之外的所有的activity。

      ② 如果新启动的activity设置了属性ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE,那么表明它并不要求后台30min的复用task删除activity。

      ③ 如果新启动的activity设置了属性ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH,那么表明不管复用task在后台是否超过30min,都要求删除除root activity之外的所有的activity。

      ④ 如果复用task中的activity设置了属性ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH,那么复用task从home中再次被启动到前台时,这个activity会被删除。

      ⑤ 如果复用task中的activity设置了属性ActivityInfo.FLAG_ALLOW_TASK_REPARENTIN,并且这个 activity的resultTo为空,那么也就是说这个activity和它的caller没有依赖关系,那么AMS认为这个activity暂时没 有用处了,需要对其进行TaskReparenting操作。

      ⑥ 如果复用task中的activity的Intent设置了属性 Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,那么下次再从home中进入到task中时,将删除设置了该属 性的activity以上所有的activity,例如A-->B-->C-->D-->E, 假如在C启动D时设置了该属性,那么下次从HOME中再次进入到这个task中时,将会是A-->B-->C。

      ⑦ 如果复用task中的activity的resultTo不为空,即启动这个activity的是一个activity,那么这个activity的处理 将按照它的前一个activity的处理方式来处理。不管在何种情况下,它的前一个activity都是启动它的activity,即便resultTo 不是前一个activity,如设置了Intent.FLAG_ACTIVITY_FORWARD_RESULT。如果复用task中每个 activity的resultTo都不为空,并且上述处理优先级在其前面的属性没有设置的话,那么这个复用task中的activity将不作任何的处 理。一般情况下,activity的resultTo都不为空,除非设置了Intent.FLAG_ACTIVITY_FORWARD_RESULT,那 么此时被启动的activity的caller的resultTo将会为空。

(1) 对于复用task中的除root activity外的activity,有如下处理方式。

     task中的activity的属性设置是上述属性的组合,因此reset task过程要按照一定的优先级来处理,上述属性的处理优先级是:⑥=④>⑦>⑤>③=②>①

     具体操作顺序如下:
     Ⅰ. 根据⑥,④条件来删除复用task中相应的activity;

     Ⅱ. ⑦条件下,将会暂时不做处理,再根据它的前一个activity的属性来做处理,即使这个activity设置了allowTaskReparenting;

     Ⅲ. 如果activity的resultTo为空,并且满足条件⑤,那么将其及其以上未作处理的,满足条件⑦的所有activity,一并进行 TaskReparenting操作,并放置在mHistory栈底。它们在mHistory栈底顺序如同在复用task中的顺序;

     Ⅳ. 根据①②③的条件来删除复用task中相应的activity。

(2) 不属于复用task的activity,并且它的resultTo不为空,那么将根据它的前一个activity的处理来处理。

(3) 不属于复用task,但是和当前启动的activity有相同affinity,并且允许TaskReparenting操作,那么将进行以下操作:
    Ⅰ. 如果满足上述的①②③④的条件,但是其中的task不是复用task,而是这个activity所处的task,那么将返回这个activity,而不是进行TaskReparenting操作。
       因为它和启动的activity有相同的affinity,因此AMS认为这个activity是和启动activity相关的,以后可能会重新调用,所 以当其满足删除条件后,这时它将不允许TaskReparenting操作,并且不应该再允许它存在于其他的task中,此时应该删除。

    Ⅱ. 如果没有满足①②③④的条件,那么将会对其进行TaskReparenting操作,重新将其移动到复用task或新启动的task中。

Task reset代码如下:

resetTaskIfNeededLocked()@ActivityStack.java

final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop, ActivityRecord newActivity) {
    boolean forceReset = (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
    if (ACTIVITY_INACTIVE_RESET_TIME > 0
                    && taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
        if ((newActivity.info.flags & ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
            forceReset = true;
        }
    }
    
    final TaskRecord task = taskTop.task;
    
    // taskFound值为false, 直到我们评价TaskRecord与taskTop相关联。因为剩余的tasks,taskFound会被设为true。在以后tasks reparenting过程中被使用。
    boolean taskFound = false;

    // 如果ActivityOptions被移除,那么需要中止或者移到taskTop。
    ActivityOptions topOptions = null;

    // 保留reparenting时在新task中的位置。
    int reparentInsertionPoint = -1;
    for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
        final TaskRecord targetTask = mTaskHistory.get(i);
    
        if (targetTask == task) {
            topOptions = resetTargetTaskIfNeededLocked(task, forceReset);
            taskFound = true;
        } else {
            reparentInsertionPoint = resetAffinityTaskIfNeededLocked(targetTask, task, taskFound, forceReset, reparentInsertionPoint);
        }
    }    
    int taskNdx = mTaskHistory.indexOf(task);
    do {
        taskTop = mTaskHistory.get(taskNdx--).getTopActivity();
    } while (taskTop == null && taskNdx >= 0);
    
    if (topOptions != null) {
        // 如果从task移除的top activity中得到有些ActivityOptions,则将它们传给新的正在的top。
        if (taskTop != null) {
            taskTop.updateOptionsLocked(topOptions);
        } else {
            topOptions.abort();
        }
    }    
    return taskTop;
}

resetTargetTaskIfNeededLocked()@ActivityStack.java

// 如果需要作为启动的一部分,对给定的task执行一个reset操作。返回task top的新的HistoryRecord。
// resetTaskIfNeededLocked的辅助方法,我们处在正在reset的task的内部,我们可能finish掉这个activity,把它推到另外一个task,或者让它保持原样。
// 参数task是包含了可能被reset的activity(taskTop)。
final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) {
    ActivityOptions topOptions = null;
    
    int replyChainEnd = -1;
    boolean canMoveOptions = true;
    
    // 只有当activity不是task的root时才做这个操作,因为如果我们finish掉root了,可能不再有task了。
    final ArrayList<ActivityRecord> activities = task.mActivities;
    final int numActivities = activities.size();
    for (int i = numActivities - 1; i > 0; --i ) {
        ActivityRecord target = activities.get(i);
    
        final int flags = target.info.flags;
        final boolean finishOnTaskLaunch = (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
        final boolean allowTaskReparenting = (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
        final boolean clearWhenTaskReset = (target.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
    
        if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) {
            // 如果这个activity正在发送一个回复给前一个activity,我们现在不能做任何事,直到我们到达回复链的开端。
            // 我们假设result总是给前一个activity,几乎总是这样,但我们真的不应该指望总是这种情况。
            if (replyChainEnd < 0) {
                replyChainEnd = i;
            }
        } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting
                   && target.taskAffinity != null && !target.taskAffinity.equals(task.affinity)) {
            // 如果这个activity有给另外一个task的affinity,那么需要将它移出这里。尽可能将它移到activity栈的底部。同时让它与之前移动的activity保持正确的顺序。
            final ActivityRecord bottom = !mTaskHistory.isEmpty() && !mTaskHistory.get(0).mActivities.isEmpty() ?
                                            mTaskHistory.get(0).mActivities.get(0) : null;
            if (bottom != null && target.taskAffinity != null && target.taskAffinity.equals(bottom.task.affinity)) {
                // 如果当前bottom的activity与我们正在移动的activity有相同的affinity,那么就将它合进同一个task中。
                target.setTask(bottom.task, bottom.thumbHolder, false);
            } else {
                target.setTask(createTaskRecord(mStackSupervisor.getNextTaskId(), target.info, null, false), null, false);
                target.task.affinityIntent = target.intent;
            }

            final TaskRecord targetTask = target.task;
            final int targetTaskId = targetTask.taskId;
            mWindowManager.setAppGroupId(target.appToken, targetTaskId);

            boolean noOptions = canMoveOptions;
            final int start = replyChainEnd < 0 ? i : replyChainEnd;
            for (int srcPos = start; srcPos >= i; --srcPos) {
                final ActivityRecord p = activities.get(srcPos);
                if (p.finishing) {
                    continue;
                }

                ThumbnailHolder curThumbHolder = p.thumbHolder;
                canMoveOptions = false;
                if (noOptions && topOptions == null) {
                    topOptions = p.takeOptionsLocked();
                    if (topOptions != null) {
                        noOptions = false;
                    }
                }
                p.setTask(targetTask, curThumbHolder, false);
                targetTask.addActivityAtBottom(p);

                mWindowManager.setAppGroupId(p.appToken, targetTaskId);
            }
    
            mWindowManager.moveTaskToBottom(targetTaskId);
            if (VALIDATE_TOKENS) {
                validateAppTokensLocked();
            }
    
            replyChainEnd = -1;
        } else if (forceReset || finishOnTaskLaunch || clearWhenTaskReset) {
            // 如果activity应该被删除,或者它要求被删除,或者task要被清除,那么finish掉它和作为它回复链的一部分的任何内容。
            int end;
            if (clearWhenTaskReset) {
                // 这种情况下,我们想要finish这个activity和它上面的所有东西,所以要假设这些都是在回复链上。
                end = numActivities - 1;
            } else if (replyChainEnd < 0) {
                end = i;
            } else {
                end = replyChainEnd;
            }
            boolean noOptions = canMoveOptions;
            for (int srcPos = i; srcPos <= end; srcPos++) {
                ActivityRecord p = activities.get(srcPos);
                if (p.finishing) {
                    continue;
                }
                canMoveOptions = false;
                if (noOptions && topOptions == null) {
                    topOptions = p.takeOptionsLocked();
                    if (topOptions != null) {
                        noOptions = false;
                    }
                }

                // 调用finishActivityLocked来finish一个activity
                if (finishActivityLocked(p, Activity.RESULT_CANCELED, null, "reset", false)) {
                    end--;
                    srcPos--;
                }
            }
            replyChainEnd = -1;
        } else {
            // 如果我们在一个链的中间,启动它的activity不想有什么特别的操作,那么保持它的原样。
            replyChainEnd = -1;
        }
    }
    return topOptions;
}

2.6.5 判断是否存在可复用的activity

 如果history中有可复用的task,那么在某些情况下并不需要启动这个activity,下面分析原因:

(1) Intent设置了Intent.FLAG_ACTIVITY_CLEAR_TOP,或者launchMode == ActivityInfo.LAUNCH_SINGLE_TASK,或者r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;这3种条件有一个共同点,就是启动的activity启动之

     后,在这个task中, 这个activity之上不能有其他的activity。

     一般情况下,需要将复用task中要启动的activity之上的所有activity删除。

    当activity的launchMode == ActivityInfo.LAUNCH_MULTIPLE,并且Intent没有设置singletop模式时,那么要删除复用task中与启动activity相同的activity,也就是不希望复用相同的activity。

    如果有可复用的activity,并且这个activity是task的root activity,由于task的Intent是root activity的Intent,所以需要重新设置task的Intent。向可复用的activity发送新的Intent,通知它Intent的变化,最终会调用到这个activity的onNewIntent()方法。

(2) 如果不满足(1)条件的话,但是启动的activity与复用task的root activity相同,那么按情况处理:

  •     如果Intent设置了Intent.FLAG_ACTIVITY_SINGLE_TOP,并且复用task的top activity正好是要启动的activity,则复用这个activity,同时更新activity的Intent,如果需要也会更新task的Intent。
  •     如果Intent没有设置了Intent.FLAG_ACTIVITY_SINGLE_TOP,即使设置了,但是当前的top activity不是正要启动的activity,那么判断如果当前启动的Intent和task的Intent不同,那么将会重新启动这个activity。
  •     其他情况,将直接resume top activity。

(3) 如果(1)(2)条件均不满足,那么复用的task中就不存在与启动的activity相同的activity了,如果启动的Intent没有设置Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,那么一定不会复用任何的activity。

(4) 如果(1)(2)条件均不满足,并且Intent设置了Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,那么需要检查当前复用task的Intent是否设置了Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED。

    如果没有设置,重新设置新的Intent, 同样不可复用activity。

    这种情况下,将不会显示要启动的activity,而是改为显示复用的task中的内容。

2.6.6 ActivityInfo.LAUNCH_SINGLE_TOP和ActivityInfo.LAUNCH_SINGLE_TASK属性的处理

    当设置Intent.FLAG_ACTIVITY_SINGLE_TOP或者launchMode == ActivityInfo.LAUNCH_SINGLE_TOP或者launchMode == ActivityInfo.LAUNCH_SINGLE_TASK这几种情况下,如果top activity与启动的activity为同一个activity,那么将复

用top activity,并直接resume top activity。

2.6.7 standard和ActivityInfo.LAUNCH_SINGLE_INSTANCE模式

    代码中为什么没有明显的针对ActivityInfo.LAUNCH_SINGLE_INSTANCE模式的处理,这是因为这种启动模式,如果Task复用失败,直接为其启动一个Intent.FLAG_ACTIVITY_NEW_TASK即可。

    (1) 设置了Intent.FLAG_ACTIVITY_NEW_TASK,则为该activity创建一个新的task。

    (2) 在当前的task中启动新的activity,

          ① 当前的caller是一个activity,如果设置Intent.FLAG_ACTIVITY_CLEAR_TOP,当前的task如果存在要启动的activity(这个和上面中的Task复用时的clear top过程不同,两者是互斥的过程,不冲突),清除其上的所有的activity。

          ② 当前的caller是一个activity,如果设置Intent.FLAG_ACTIVITY_REORDER_TO_FRONT,这个flag表示如果启动的activity已经在当前的task中,那么如果当前启动的Intent设置了该flag,那么则会将这个activity从task中移动到top。

             如果A-->B-->C-->D,D启动B时,设置了该flag,那么将变为A-->C-->D-->B。

             ①②两个条件,都不需要再启动新的activity,直接resume top。        

         ③ 当前的caller是一个activity,其他情况则需要启动新的activity。

    (3) 当前的caller不是activity,那么仍将新启动的activity放在top的task中。

转载于:https://www.cnblogs.com/Jackwen/p/5135902.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用以下命令安装 workflow-bpmn-modeler: 1. 使用 npm 安装: ``` npm install [email protected] [email protected] [email protected] [email protected] [email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/external_task[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/process[email protected] @process-engine/process[email protected] @process-engine/process[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/user_task[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/empty_user_task[email protected] @process-engine/empty_activity[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/empty_activity[email protected] @process-engine/[email protected] @process-engine/empty_user_task[email protected] ``` 2. 使用 yarn 安装: ``` yarn add [email protected] [email protected] [email protected] [email protected] [email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/external_task[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/process[email protected] @process-engine/process[email protected] @process-engine/process[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/user_task[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/empty_user_task[email protected] @process-engine/empty_activity[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/[email protected] @process-engine/empty_activity[email protected] @process-engine/[email protected] @process-engine/empty_user_task[email protected] ``` 安装完成后,您可以在项目中使用 workflow-bpmn-modeler。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值