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没有关系。java
1. 建立ActivityRecordandroid
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检查app
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.javaui
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.javathis
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的建立与管理spa
2.1 Task与Application的区别3d
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相同,那么按状况处理:
(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中。