二、Activity 的启动模式
一、四种启动模式:
① standard(标准模式)
这个是系统的默认模式。在这种模式下,每次启动一个 Activity 都会重新创建一个新的实例,不管这个实例是否已经存在,并且谁启动了这个 Activity,那么这个 Activity 就运行在启动它的那个 Activity 所在的栈中。
eg:
// FirstActivity.java
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);// SecondActivity.java
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
startActivity(intent);// ThirdActivity.java
Intent intent = new Intent(ThirdActivity.this, FirstActivity.class);
startActivity(intent);
FirstActivity.java -> SecondActivity.java -> ThirdActivity.java -> FirstActivity.java:
执行 adb shell dumpsys activity:
可以看到结果中,只有一个名为 com.cfm.launchermodeActivity 的任务栈,并且每启动一个 activity,都会创建一个相应的实例。
问题引入:当我们使用 ApplicationContext 去启动 standard 模式的 Activity 的时候会报错,为什么? 因为 standard 模式的 Activity 默认会进入启动它的 Activity 所属的任务栈中,但是由于非 Activity 类型的 Context(如ApplicationContext)并没有所属的任务栈,所以就会报错。解决方法就是为待启动的 Activity 指定 FLAG_ACTIVITY_NEW_TASK 标记位,这样启动的时候就会为它创建一个新的任务栈。
② singleTop(栈顶复用模式)
在这种模式下,如果新 Activity 已经位于任务栈的栈顶,那么此 Activity 不会被重新创建,同时它的 onNewIntent() 方法会被回调,通过此方法的参数我们可以得到当前请求的信息。由于这个 activity 并没有被重新创建,所以它的 onCreate()、onStart() 都不会被系统调用。
// FirstActivity.java
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);// SecondActivity.java
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
startActivity(intent);// ThirdActivity.java
Intent intent = new Intent(ThirdActivity.this,ThirdActivity.class);
startActivity(intent);@Override
protected void onNewIntent(Intent intent) {super.onNewIntent(intent);Log.d("test", "onNewIntent() 被回调了");
}在 AndroidManifest.xml 为 ThirdActivity 指定启动模式为 singleTop:
<activity android:name=".ThirdActivity"android:launchMode="singleTop">
</activity>
FirstActivity.java -> SecondActivity.java -> ThirdActivity.java ->ThirdActivity.java ->ThirdActivity.java:
Log日志:
结果可以看到,任务栈中只有一个 ThirdActivity 实例,并且 ThirdActivity 中的 onNewIntent() 方法被调用了两次。
③ singleTask(栈内复用模式)
这是一种单实例模式,在这种模式下,只要 Activity 在要进入的任务栈中存在,那么多次启动此 Activity 都不会重新创建实例,和 singleTop 一样,系统也会回调 onNewIntent()。并且 singleTask 默认具有 clearTop 效果,也就是说如果这个 Activity 不在栈顶时,它会把它上面的 Activity 顶出栈以让自己处于栈顶位置。如果要进入的栈不存在就先创建相应的任务栈,然后再入栈。
// FirstActivity.java
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);// SecondActivity.java
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
startActivity(intent);@Override
protected void onNewIntent(Intent intent) {super.onNewIntent(intent);Log.d("SecondActivity", "onNewIntent() 被回调了");
}// ThirdActivity.java
Intent intent = new Intent(ThirdActivity.this, SecondActivity.class);
startActivity(intent);在 AndroidManifest.xml 为 SecondActivity 指定启动模式为 singleTask:
<activity android:name=".SecondActivity"android:launchMode="singleTask">
</activity>
FirstActivity.java -> SecondActivity.java -> ThirdActivity.java ->SecondActivity.java:
Log日志:
从结果可以看出,当第二次启动 SecondActivity 时,由于之前的任务栈中已经有了此实例,所以它就不会被再次创建,而是直接使用之前的实例并回调 onNewIntent() 方法,并且 SecondActivity 上面的 Activity 也会被出栈。
④ singleInstance(单实例模式)
这是一种加强的 singleTask 模式,它除了具有 singleTask 模式的所有特性外,还加强了一点,那就是具有此模式的 Activity 只能单独地位于一个任务栈中,由于栈内复用特性(singleTask 中的特性),后续请求均不会创建新的 Activity,并且还会回调 onNewIntent() 方法。
// FirstActivity.java
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);// SecondActivity.java
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
startActivity(intent);@Override
protected void onNewIntent(Intent intent) {super.onNewIntent(intent);Log.d("SecondActivity", "onNewIntent() 被回调了");
}// ThirdActivity.java
Intent intent = new Intent(ThirdActivity.this, SecondActivity.class);
startActivity(intent);在 AndroidManifest.xml 为 SecondActivity 指定启动模式为 singleInstance:
<activity android:name=".SecondActivity"android:launchMode="singleInstance">
</activity>
FirstActivity.java -> SecondActivity.java -> ThirdActivity.java ->SecondActivity.java:
Log日志:
二、TaskAffinity(任务相关性):
TaskAffinity 参数可以翻译为任务相关性,它标识了一个 Activity 所需要的任务栈的名字,默认情况下,所有 Activity 所需任务栈的名字为应用的包名。我们可以通过 TaskAffinity 属性来设置当前 Activity 的任务栈名称,这个属性主要和 singleTask 启动模式和 allowTaskReparenting 属性配合使用,在其它情况下没有意义。另外,任务栈分为前台任务栈和后台任务栈,后台任务栈中的 Activity 处于暂停状态,用户可以通过切换将后台任务栈再次调到前台。
TaskAffinity + singleTask 模式:
指定 Activity 启动后任务栈的名称。
TaskAffinity + allowTaskReparenting 属性:
allowTaskReparenting 属性的作用是 Activity 迁移。当 allowTaskReparenting 属性和 TaskAffinity 配合使用时,Activity 可以从一个任务栈迁移到另一个任务栈。迁移的规则是:从一个与该 Activity 的 TaskAffinity 属性不同的任务栈中迁移到与 该 Activity 的 TaskAffinity 属性相同的任务栈中。
这个比较抽象,举个例子:应用 A 中的 Activity a 和应用 B 中的 Activity b。a 启动 b 时,当 b 的 allowTaskReparenting 属性为 false 时,b 会在 a 的任务栈上创建实例;当 b 的 allowTaskReparenting 属性为 true 时,因为 a 和 b 的 TaskAffinity 属性不同,所以 b 会从 a 的 task 中迁移到 b 中 TaskAffinity 所表示的任务栈,如果这时启动应用 B ,由于 B 的任务栈已经存在,所以直接就会进入 b 界面。
三、为 Activity 指定启动模式:
① 通过 AndroidManifest.xml 文件指定 “launchMode”属性,eg:
<activity android:name=".SecondActivity"android:launchMode="singleInstance">
</activity>
② 通过 java 代码在 intent 中设置标志位:
Intent intent = new Intent();
intent.setClass(FirstActivity.this, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
二者的区别为:优先级上,第二种比第一种高,当两个同时指定以第二种方式为准;其次,各自的限定范围有所不同,比如第一种无法直接为 Activity 设定 FLAG_ACTIVITY_CLEAR_TOP 标识,而第二种无法为 Activity 指定 singleInstance 模式。总的来说,在能满足自己的需求范围内,使用哪种方式都可以。
四、Intent 中常用的 FLAG:
① FLAG_ACTIVITY_CLEAR_TOP:
这里分两种情况:
a. 当设置的这个 activity 在当前的 Task 中存在,并且启动模式为 standard 而且没有为这个 intent 中设置 FLAG_ACTIVITY_SINGLE_TOP 标志,此时它会清除这个栈中在它之上的(包括它自己)所有的 activity,然后重新创建这个 activity;
b. 当设置的这个 activity 在当前的 Task 中存在,并且启动模式不为 standard 或者为这个 intent 中设置了FLAG_ACTIVITY_SINGLE_TOP 标志,此时它会清除这个栈中在它之上的(不包括它自己)所有的 activity,然后将这个 activity 重新回到栈顶并调用它的 onNewIntent() 方法;
② FLAG_ACTIVITY_SINGLE_TOP:
效果和在 AndroidManifest.xml 中指定的 launchMode 为 singleTop 一样。
③ FLAG_ACTIVITY_SINGLE_TASK:
效果和在 AndroidManifest.xml 中指定的 launchMode 为 singleTask一样。
④ FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:
如果设置,新的 activity 不会在最近启动的 activity 的列表中保存。
二、Activity 的启动模式相关推荐
- Android Activity的启动模式及对生命周期的影响
Activity的启动模式 官网解释链接 (tips:在阅读此文章前,应先对Activity生命周期掌握) 在每一个程序的main目录下有一个AndroidManifest.xml文件,这个文件是用来 ...
- Activity的启动模式详解
Activity的启动模式详解 Activity有四种载入模式:standard(默认), singleTop, singleTask和 singleInstance. (1).standard(默认 ...
- Android入门(六) | Activity 的启动模式 及 生产环境中关于 Activity 的小技巧
文章目录 Activity 的启动模式 standard singleTop singleTask singleInstance 技巧 了解当前界面是哪个 Activity 随时随地退出程序 启动活动 ...
- Android 源码分析 Activity的启动模式
一直想抽空针对AMS进行源码分析,无奈一方面因为很忙,另外AMS很复杂,涉及的知识点也比较多,今天利用五一假期对AMS的一个方面,Activity的启动模式进行源码分析,这里面包括了ActivityR ...
- Android中Activity的启动模式和使用场景
一.为什么需要启动模式 在Android开发中,我们都知道,在默认的情况下,如果我们启动的是同一个Activity的话,系统会创建多个实例并把它们一一放入任务栈中.当我们点击返回(back)键,这些A ...
- Activity(三)—— Activity的启动模式
Activity的启动模式 1 Activity的LaunchMode Activity为什么需要启动模式?在默认情况下,当我们多次启动同一个Activity的时候,系统会创建多个实例并把它们一一放入 ...
- Activity的启动模式
题目:Activity的启动模式,区别 这道题想考察什么? 启动模式是什么? 启动模式如何设置? Activity的启动模式区别? 应用场景以及那些注意的点? 考察的知识点 启动任务,返回栈,启动模式 ...
- activity 启动模式_Android世界:Activity的启动模式及其适用范围
一.Activity启动模式简介 activity启动模式,可以理解为activity在任务栈(也叫"回退栈")的回退规则,即点击"back"键时,activi ...
- Activity的启动模式与flag详解
Activity有四种加载模式:standard(默认), singleTop, singleTask和 singleInstance.以下逐一举例说明他们的区别: standard:Activity ...
最新文章
- eclipse中启动tomcat出现错误的解决方法
- android vlc eclipse,在Eclipse下导入vlc-android并编译
- 的tree用法_linux命令tree用法
- java 动态增加定时任务
- php cache-control,网页缓存控制 Cache-control 常见的取值有private、no-cache、max-age、must-revalidate 介绍...
- Ark CEO:本次比特币下跌属于健康回调
- iview tooltip自动消失_实现自动驾驶,为什么要对汽车、行人的轨迹进行预测?它与物体检测、追踪和路径规划间的关系是什么?...
- 部署VC2008应用程序时不能运行解决办法
- 使用vscode作为golang开发环境,无法跳转代码定义
- 英语论文引用中的常用缩写含义
- HQChart实战教程6-自定义分时图
- Python:第三方模块phonenumbers 解析全球电话号码
- java动态代理三座大山InvocationHandler、newProxyInstance()和invoke()
- python3入门笔记
- php发送 日历邮件_如何阻止垃圾邮件发送者攻击您的Google日历
- Android 应用层组件安全测试基础实战技巧
- excel统计求和:如何在合并后的单元格中复制求和公式
- 移动应用开发测试工具Bugtags集成和使用教程
- 【AnySDK】目前对外开放的渠道列表
- mesh导出OBJ、STL格式和win窗口调用