一、Activity简介
Activity是四大组件中最重要的一个,也是平时开发中接触最多的。与Activity启动行为相关的就是它的启动模式,Standard、SingleTop、SingleTask、SingleInstance这4种launchMode相信大家不陌生。
OK,熟悉了4种launchMode后相信你已经对Activity任务栈有一些理解了,能应对一些常见的开发场景了。然而,除了4种launchMode,还有更复杂的控制Activity行为的方式,那就是给启动Activity的Intent添加flag,使用 Intent.addFlags(int flags) 方法。
看一下这个方法的参数,总共有20种:
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT, Intent.FLAG_ACTIVITY_CLEAR_TASK, Intent.FLAG_ACTIVITY_CLEAR_TOP, Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET, Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS, Intent.FLAG_ACTIVITY_FORWARD_RESULT, Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY, Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT, Intent.FLAG_ACTIVITY_MULTIPLE_TASK, Intent.FLAG_ACTIVITY_NEW_DOCUMENT, Intent.FLAG_ACTIVITY_NEW_TASK, Intent.FLAG_ACTIVITY_NO_ANIMATION, Intent.FLAG_ACTIVITY_NO_HISTORY, Intent.FLAG_ACTIVITY_NO_USER_ACTION, Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT, Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS, Intent.FLAG_ACTIVITY_SINGLE_TOP, Intent.FLAG_ACTIVITY_TASK_ON_HOME,
这么多估计大家一看就晕了,我一开始也是这样。不过,仔细看每一条的文档,把它添加到你要启动的Activity上,然后观察Activity的行为,这样就容易弄明白它的含义。
二、任务栈相关概念
在分析具体的flag之前,介绍一些Activity任务栈相关的概念:Activity、task、tasks、recent tasks list。这些概念都是抽象的,除了Activity和recent tasks list看得见之外,其他都是看不见摸不着的。
如果没有直观的视觉感受,即使我说得天花乱坠你也可能还是云里雾里,而有了图甚至动画直接展示它们就不一样了。下面这个工具能很好地帮助我们:
https://github.com/rome753/ActivityTaskView
有了ActivityTaskView,就能结合图来分析了。
1、Activity 活动,这个就不用解释了
2、task 任务
它是应用中的放置活动的一个类似于栈的结构。栈顶的是最上面的活动,也就是用户直接看到的页面,顶部以下的活动都处于onStop状态(如果是可见的,那么处于onPause状态)。一般连续按返回键能自顶向下销毁活动。上图中的悬浮窗表示一个任务,在这个任务中启动了20多个活动。
3. tasks 一个应用的所有任务
虽然单个task是比较常见的应用,但是一个应用可以有多个task,创建新的task有好几种方法。
4. recent tasks list 最近任务列表
老的安卓系统中长按home键出现的页面,新的系统直接按导航栏中的正方形按钮。这个列表表示最近启动的应用的tasks,表中每一项表示一个入口。需要注意的是,一个应用可能会出现多个入口,因为应用可能有多个任务,当然不一定每个任务都会出现在列表中。
三、常用flag
1、FLAG_ACTIVITY_NEW_TASK
设置这个flag,新启动的activity就会被放置到一个新的任务当中(与"singleTask"有点类似,但不完全一样),当然这里讨论的还是启动其他应用程序的activity。这个flag的作用通常是模拟一种Launcher的行为,即列出一推可以启动的东西,但启动的每一个Activity都是在运行在自己独立的任务当中的。
2、FLAG_ACTIVITY_CLEAR_TOP
设置了这个flag,如果要启动的Activity在当前任务中已经存在了,并且还处于栈顶的位置,那么就不会再次创建这个Activity的实例,而是直接调用它的onNewIntent()方法。这种flag和在launchMode中指定"singleTop"模式所实现的效果是一样的。
3、FLAG_ACTIVITY_SINGLE_TOP
设置了这个flag,如果要启动的Activity在当前任务中已经存在了,就不会再次创建这个Activity的实例,而是会把这个Activity之上的所有Activity全部关闭掉。比如说,一个任务当中有A、B、C、D四个Activity,然后D调用了startActivity()方法来启动B,并将flag指定成FLAG_ACTIVITY_CLEAR_TOP,那么此时C和D就会被关闭掉,现在返回栈中就只剩下A和B了。
四、结束当前Activity
方法1
finish();
方法2
System.exit(0);
方法3
android.os.Process.killProcess(android.os.Process.myPid());
方法4
this.onDestory();
五、Intent跳转Activity
1、假设目前已经启动了3个Activity,分别叫做FirstActivity,SecondActivity,ThirdActivity,现在想在ThirdActivity中跳转至FirstActivity,即再启动一个FirstActivity,但不是变成1,2,3,1,而是变成1,即销毁掉中间所有的activity,同时要求保留FirstActivity上的数据。
Intent intent = new Intent(this,FirstActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//关掉所要到的界面中间的activity intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);//设置不要刷新将要跳转的界面 startActivity(intent);
2、与1类似,假设目前已经启动了3个Activity,分别叫做FirstActivity,SecondActivity,ThirdActivity,现在想在ThirdActivity中跳转至FirstActivity,即再启动一个FirstActivity,但不是变成1,2,3,1,而是变成1,即销毁掉中间所有的activity,这里要求不保留FirstActivity上的数据。
Intent intent = new Intent(this,FirstActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//关掉所要到的界面中间的activity startActivity(intent);
3、假设目前已经启动了3个Activity,分别叫做FirstActivity,SecondActivity,ThirdActivity,现在想在
Intent intent = new Intent(this,FirstActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(intent);
参考文章:
https://zhuanlan.zhihu.com/p/23704495