一、四种启动模式:

① 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 的启动模式相关推荐

  1. Android Activity的启动模式及对生命周期的影响

    Activity的启动模式 官网解释链接 (tips:在阅读此文章前,应先对Activity生命周期掌握) 在每一个程序的main目录下有一个AndroidManifest.xml文件,这个文件是用来 ...

  2. Activity的启动模式详解

    Activity的启动模式详解 Activity有四种载入模式:standard(默认), singleTop, singleTask和 singleInstance. (1).standard(默认 ...

  3. Android入门(六) | Activity 的启动模式 及 生产环境中关于 Activity 的小技巧

    文章目录 Activity 的启动模式 standard singleTop singleTask singleInstance 技巧 了解当前界面是哪个 Activity 随时随地退出程序 启动活动 ...

  4. Android 源码分析 Activity的启动模式

    一直想抽空针对AMS进行源码分析,无奈一方面因为很忙,另外AMS很复杂,涉及的知识点也比较多,今天利用五一假期对AMS的一个方面,Activity的启动模式进行源码分析,这里面包括了ActivityR ...

  5. Android中Activity的启动模式和使用场景

    一.为什么需要启动模式 在Android开发中,我们都知道,在默认的情况下,如果我们启动的是同一个Activity的话,系统会创建多个实例并把它们一一放入任务栈中.当我们点击返回(back)键,这些A ...

  6. Activity(三)—— Activity的启动模式

    Activity的启动模式 1 Activity的LaunchMode Activity为什么需要启动模式?在默认情况下,当我们多次启动同一个Activity的时候,系统会创建多个实例并把它们一一放入 ...

  7. Activity的启动模式

    题目:Activity的启动模式,区别 这道题想考察什么? 启动模式是什么? 启动模式如何设置? Activity的启动模式区别? 应用场景以及那些注意的点? 考察的知识点 启动任务,返回栈,启动模式 ...

  8. activity 启动模式_Android世界:Activity的启动模式及其适用范围

    一.Activity启动模式简介 activity启动模式,可以理解为activity在任务栈(也叫"回退栈")的回退规则,即点击"back"键时,activi ...

  9. Activity的启动模式与flag详解

    Activity有四种加载模式:standard(默认), singleTop, singleTask和 singleInstance.以下逐一举例说明他们的区别: standard:Activity ...

最新文章

  1. eclipse中启动tomcat出现错误的解决方法
  2. android vlc eclipse,在Eclipse下导入vlc-android并编译
  3. 的tree用法_linux命令tree用法
  4. java 动态增加定时任务
  5. php cache-control,网页缓存控制 Cache-control 常见的取值有private、no-cache、max-age、must-revalidate 介绍...
  6. Ark CEO:本次比特币下跌属于健康回调
  7. iview tooltip自动消失_实现自动驾驶,为什么要对汽车、行人的轨迹进行预测?它与物体检测、追踪和路径规划间的关系是什么?...
  8. 部署VC2008应用程序时不能运行解决办法
  9. 使用vscode作为golang开发环境,无法跳转代码定义
  10. 英语论文引用中的常用缩写含义
  11. HQChart实战教程6-自定义分时图
  12. Python:第三方模块phonenumbers 解析全球电话号码
  13. java动态代理三座大山InvocationHandler、newProxyInstance()和invoke()
  14. python3入门笔记
  15. php发送 日历邮件_如何阻止垃圾邮件发送者攻击您的Google日历
  16. Android 应用层组件安全测试基础实战技巧
  17. excel统计求和:如何在合并后的单元格中复制求和公式
  18. 移动应用开发测试工具Bugtags集成和使用教程
  19. 【AnySDK】目前对外开放的渠道列表
  20. mesh导出OBJ、STL格式和win窗口调用

热门文章

  1. mysql 创建索引语句
  2. android服务应用实验报告,Service与Broadcast应用实验报告
  3. android摄像头代码,android: 调用摄像头拍照(示例代码)
  4. DELPHI实现网络PING的功能
  5. Python趣味代码(一):微信信息轰炸
  6. 苹果vs剪辑下载_我常用的三个剪辑工具 免费功能强大 剪辑视频不再求人
  7. 全角转半角,JAVA对中文的处理
  8. 基于AT89C51单片机的简易计算机设计
  9. 无论环境如何,都要获得高精度、多通道的温度测量
  10. kuangbin数学训练2