If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started. That is, the activity becomes the new root of an otherwise empty task, and any old activities are finished. This can only be used in conjunction with FLAG_ACTIVITY_NEW_TASK.
这个属性必须同FLAG_ACTIVITY_NEW_TASK配合使用,如果设置了FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK,如果目标task已经存在,将清空已存在的目标Task,否则,新建一个Task栈,之后,新建一个Activity作为根Activity。Intent.FLAG_ACTIVITY_CLEAR_TASK的优先级最高,基本可以无视所有的配置,包括启动模式及Intent Flag,哪怕是singleInstance也会被finish,并重建。
Intent.FLAG_ACTIVITY_CLEAR_TOP
如果没有使用FLAG_ACTIVITY_NEW_TASK,目标是当前Task栈,根据不同的组合会产生不同的效果,如果单独使用Intent.FLAG_ACTIVITY_CLEAR_TOP,并且没有设置特殊的launchmode,那么,Google官方的示例是:如果ABCD Task中的D采用Intent.FLAG_ACTIVITY_CLEAR_TOP唤起B,这个时候首先会将CD出栈,但是至于B是否会重建,要视情况而定,如果没有设置FLAG_ACTIVITY_SINGLE_TOP,则会将B finish掉,之后创建新的入栈。如果同一个栈中原来有
如果没有则新建,不会去另一个栈中寻找。
如果同时设置了FLAG_ACTIVITY_SINGLE_TOP,在当前栈已有的情况下就不会重建,而是直接回调B的onNewIntent(),
官方解释如下:
For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B。
The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. If it has declared its launch mode to be “multiple” (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be delivered to the current instance’s onNewIntent().
如果同时使用了FLAG_ACTIVITY_NEW_TASK ,这个时候,目标是Activity自己所属的Task栈,如果在自己的Task中能找到一个Activity实例,则将其上面的及自身清理掉,之后重建。
如果同时在加上FLAG_ACTIVITY_SINGLE_TOP,会更特殊一些,如果topActivity不是目标Activity,就会去目标Task中去找,并唤起
如果topActivity是目标Activity,就直接回调topActivity的onNewIntent,无论topActivity是不是在目标Task中
Intent.FLAG_ACTIVITY_SINGLE_TOP
Intent.FLAG_ACTIVITY_SINGLE_TOP多用来做辅助作用,跟launchmode中的singleTop作用一样,在Task栈顶有的话,就不新建,栈顶没有的话,就新建,这里的Task可能是目标栈,也可能是当前Task栈,配合FLAG_ACTIVITY_NEW_TASK及FLAG_ACTIVITY_CLEAR_TOP都会有很有意思的效果。
源码分析
现在我们看一下源码,来分析下原理:从源码更能看出FLAG_ACTIVITY_NEW_TASK重要性,这里只分析部分场景,不然太多了: 下面的是4.3的代码,比较简单些:
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();
…
// 如果sourceRecord ==null 说明不是从activity启动的,从服务开启就一定要start a new task
if (sourceRecord == null) {
if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
}
} else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
} else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
}
…
if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
sendActivityResultLocked(-1,
r.resultTo, r.resultWho, r.requestCode,
Activity.RESULT_CANCELED, null);
r.resultTo = null;
}
boolean addingToTask = false;
boolean movedHome = false;
TaskRecord reuseTask = null;
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) {
if (r.resultTo == null) {
ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
?findTaskLocked(intent, r.info)
: findActivityLocked(intent, r.info);
if (taskTop != null) {
ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop);
if (curTop != null && curTop.task != taskTop.task) {
r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
boolean callerAtFront = sourceRecord == null
|| curTop.task == sourceRecord.task;
if (callerAtFront) {
movedHome = true;
moveHomeToFrontFromLaunchLocked(launchFlags);
moveTaskToFrontLocked(taskTop.task, r, options);
options = null;
}
}
…
if ((launchFlags &
(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
== (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
reuseTask = taskTop.task;
performClearTaskLocked(taskTop.task.taskId);
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) {
ActivityRecord top = performClearTaskLocked(
taskTop.task.taskId, r, launchFlags);
if (top != null) {
if (top.frontOfTask) {
top.task.setIntent(r.intent, r.info);
}
top.deliverNewIntentLocked(callingUid, r.intent);
} else {
addingToTask = true;
sourceRecord = taskTop;
}
} else if (r.realActivity.equals(taskTop.task.realActivity)) {
if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
&& taskTop.realActivity.equals(r.realActivity)) {
if (taskTop.frontOfTask) {
taskTop.task.setIntent(r.intent, r.info);
}
taskTop.deliverNewIntentLocked(callingUid, r.intent);
} else if (!r.intent.filterEquals(taskTop.task.intent)) {
addingToTask = true;
sourceRecord = taskTop;
}
}
…
if (!addingToTask && reuseTask == null) {
if (doResume) {
resumeTopActivityLocked(null, options);
} else {
ActivityOptions.abort(options);
}
return ActivityManager.START_TASK_TO_FRONT;
}
}
}
}
if (r.packageName != null) {
ActivityRecord top = 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) {
logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
if (doResume) {
resumeTopActivityLocked(null);
}
ActivityOptions.abort(options);
if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
return ActivityManager.START_RETURN_INTENT_TO_CALLER;
}
top.deliverNewIntentLocked(callingUid, r.intent);
return ActivityManager.START_DELIVERED_TO_TOP;
}
}
}
}
}
…
boolean newTask = false;
boolean keepCurTransition = false;
if (r.resultTo == null && !addingToTask
&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
if (reuseTask == null) {
mService.mCurTask++;
if (mService.mCurTask <= 0) {
mService.mCurTask = 1;
}
r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true);
} else {
r.setTask(reuseTask, reuseTask, true);
}
newTask = true;
if (!movedHome) {
moveHomeToFrontFromLaunchLocked(launchFlags);
}
} else if (sourceRecord != null) {
if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
ActivityRecord top = performClearTaskLocked(
sourceRecord.task.taskId, r, launchFlags);
keepCurTransition = true;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
![](https://i-blog.csdnimg.cn/blog_migrate/eedb24384e9ba2c1b43b5933977fb2b9.jpeg)
最后
愿你有一天,真爱自己,善待自己。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
以扫码获取!!(备注:Android)**
![](https://i-blog.csdnimg.cn/blog_migrate/eedb24384e9ba2c1b43b5933977fb2b9.jpeg)
最后
愿你有一天,真爱自己,善待自己。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!