Android 之Activity启动模式(二)之 Intent的Flag属性
前面介绍了通过launchMode设置Activity的启动模式。本章接着介绍Activity的启动模式相关内容,讲解的内容是Intent与启动模式相关的Flag,以及android:taskAffinity的属性。
目录
1. Intent与启动模式相关的Flag简介
2. 1.
FLAG_ACTIVITY_NEW_TASK标签测试
3. 2.
FLAG_ACTIVITY_CLEAR_TOP标签测试
4. 3.
FLAG_ACTIVITY_CLEAR_TASK标签测试
5. 4.
FLAG_ACTIVITY_SINGLE_TOP标签测试
Intent与启动模式相关的Flag简介
这里仅仅对几个常用的与启动模式相关的Flag进行介绍。
FLAG_ACTIVITY_NEW_TASK
在google的官方文档中介绍,它与launchMode="singleTask"具有相同的行为。实际上,并不是完全相同!
很少单独使用FLAG_ACTIVITY_NEW_TASK,通常与FLAG_ACTIVITY_CLEAR_TASK或FLAG_ACTIVITY_CLEAR_TOP联合使用。因为单独使用该属性会导致奇怪的现象,通常达不到我们想要的效果!尽管如何,后面还是会通过"FLAG_ACTIVITY_NEW_TASK示例一"和"FLAG_ACTIVITY_NEW_TASK示例二"会向你展示单独使用它的效果。FLAG_ACTIVITY_SINGLE_TOP
在google的官方文档中介绍,它与launchMode="singleTop"具有相同的行为。实际上,的确如此!单独的使用FLAG_ACTIVITY_SINGLE_TOP,就能达到和launchMode="singleTop"一样的效果。FLAG_ACTIVITY_CLEAR_TOP
顾名思义,FLAG_ACTIVITY_CLEAR_TOP的作用清除"包含Activity的task"中位于该Activity实例之上的其他Activity实例。FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_NEW_TASK两者同时使用,就能达到和launchMode="singleTask"一样的效果!FLAG_ACTIVITY_CLEAR_TASK
FLAG_ACTIVITY_CLEAR_TASK的作用包含Activity的task。使用FLAG_ACTIVITY_CLEAR_TASK时,通常会包含FLAG_ACTIVITY_NEW_TASK。这样做的目的是启动Activity时,清除之前已经存在的Activity实例所在的task;这自然也就清除了之前存在的Activity实例!
注意:当同时使用launchMode和上面的FLAG_ACTIVITY_NEW_TASK等标签时,以FLAG_ACTIVITY_NEW_TASK为标准。也就是说,代码的优先级比manifest中配置文件的优先级更高!
下面,通过几个实例加深对这几个标记的理解。
1. FLAG_ACTIVITY_NEW_TASK标签测试
1.1 FLAG_ACTIVITY_NEW_TASK示例一
点击查看:FLAG_ACTIVITY_NEW_TASK示例一的源码
在该实例中,有两个Activity:ActivityTest和SecondActivity。manifest定义如下:
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
<activity android:name="ActivityTest"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="SecondActivity" />
</application>
说明:通过manifest可以看出,ActivityTest和SecondActivity在同一个APK中。这也就意味着它们的android:taskAffinity是一样的!
ActivityTest的源码
public class ActivityTest extends Activity {
private static final String TAG="##ActivityTest##";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(TAG, "onCreate: "+this.toString()+", taskId="+this.getTaskId());
TextView tv = (TextView) findViewById(R.id.tv);
tv.setText(this.toString()+", taskId="+this.getTaskId());
}
public void onJump(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
@Override
protected void onNewIntent(Intent intent) {
Log.d(TAG, "onNewIntent: intent="+intent+", activity="+this+", taskId="+this.getTaskId());
}
}
说明:onJump()是ActivityTest中一个按钮的回调函数,点击该按钮会跳转到SecondActivity。注意,跳转的Intent添加了FLAG_ACTIVITY_NEW_TASK标志。
SecondActivity的源码
public class SecondActivity extends Activity {
private static final String TAG="##SecondActivity##";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
Log.d(TAG, "onCreate: "+this.toString()+", taskId="+this.getTaskId());
TextView tv = (TextView) findViewById(R.id.tv2);
tv.setText(this.toString()+", taskId="+this.getTaskId());
}
public void onBack(View view) {
Intent intent = new Intent(this, ActivityTest.class);
startActivity(intent);
}
@Override
protected void onNewIntent(Intent intent) {
Log.d(TAG, "onNewIntent: intent="+intent+", activity="+this+", taskId="+this.getTaskId());
}
}
说明:onBack()是SecondActivity中一个按钮的回调函数,点击该按钮会跳转回ActivityTest。
测试内容:ActivityTest --> SecondActivity --> ActivityTest --> SecondActivity
测试结果:(01) ActivityTest和SecondActivity在同一个task中。 (02) 两个SecondActivity不同的实例!
结果分析:如果说FLAG_ACTIVITY_NEW_TASK的作用和singleTask具有相同的效果。那么这个示例很明显的否则了这个结论!事实上,在相互跳转的两个Activity的android:taskAffinity相同的情况下,单独使用FLAG_ACTIVITY_NEW_TASK不会产生任何效果!
那如果两个Activity的android:taskAffinity不相同呢?此时会导致什么效果呢?下面,我们通过示例来看看效果。
1.2 FLAG_ACTIVITY_NEW_TASK示例二
点击查看:FLAG_ACTIVITY_NEW_TASK示例二的源码
我们修改"FLAG_ACTIVITY_NEW_TASK示例一"中manifest,将ActivityTest和SecondActivity的android:taskAffinity改为不同;其余的保持不变!修改后的manifest如下:
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
<activity android:name="ActivityTest"
android:taskAffinity="com.skw.activitytest01"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="SecondActivity"
android:taskAffinity="com.skw.activitytest02"
/>
</application>
测试内容:ActivityTest --> SecondActivity --> ActivityTest --> SecondActivity
测试结果:(01) ActivityTest和SecondActivity在不同task中! (02) 当第二次进入到ActivityTest中,再企图从ActivityTest中进入到SecondActivity时,没有产生任何效果,仍然停留在ActivityTest中!即第二次ActivityTest --> SecondActivity压根就没发生!
结果分析:当相互跳转的两个Activity的android:taskAffinity不同时,添加FLAG_ACTIVITY_NEW_TASK确实产生了一些效果:第一次启动Activity时,会新建一个task,并将Activity添加到该task中。这与singleTask产生的效果是一样的!但是,当企图再次从ActivityTest进入到SecondActivity时,却什么也没有发生!
为什么呢?是因为此时SecondActivity实例已经存在,但是它所在的task的栈顶是ActivityTest;而单独的添加FLAG_ACTIVITY_NEW_TASK又不会"删除task中位于SecondActivity之上的Activity实例",所以就没有发生跳转!
好的,那下面,我们添加FLAG_ACTIVITY_CLEAR_TOP之后,再来看看效果。
2. FLAG_ACTIVITY_CLEAR_TOP标签测试
2.1 FLAG_ACTIVITY_CLEAR_TOP示例一
点击查看:FLAG_ACTIVITY_CLEAR_TOP示例一的源码。
我们修改"FLAG_ACTIVITY_NEW_TASK示例一"中onJump()函数,修改后的代码如下:
public void onJump(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
测试内容:ActivityTest --> SecondActivity --> ActivityTest --> SecondActivity
测试结果:(01) ActivityTest和SecondActivity在同一个task中! (02) 两个SecondActivity是不同的实例。
结果分析:这与没有添加FLAG_ACTIVITY_CLEAR_TOP时效果一样!这说明,当相互跳转的两个Activity的android:taskAffinity一样时,不会产生任何效果!
接下来,看看不同android:taskAffinity的情况。
2.2 FLAG_ACTIVITY_CLEAR_TOP示例二
点击查看:FLAG_ACTIVITY_CLEAR_TOP示例二的源码。
我们修改"FLAG_ACTIVITY_NEW_TASK示例一"中onJump()函数,修改后的代码如下:
public void onJump(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
测试内容:ActivityTest --> SecondActivity --> ActivityTest --> SecondActivity
测试结果:(01) ActivityTest和SecondActivity在不同task中! (02) 两个SecondActivity是同一个实例。
结果分析:此时的表现和SecondActivity是singleTask一样! 这说明,在相互跳转的Activity的android:taskAffinity不同时,同时使用FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TOP,才具有和singleTask一样的效果!
总的来说:FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TOP的使用和android:taskAffinity相关。在同时使用FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TOP的情况下,以A启动B来说
(01) 当A和B的taskAffinity相同时:添加FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TOP没有任何作用。和没有添加时的效果一样!
(02) 当A和B的taskAffinity不同时:添加FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TOP后,表现的和B是singleTask一样!
3. FLAG_ACTIVITY_CLEAR_TASK标签测试
3.1 FLAG_ACTIVITY_CLEAR_TASK示例一
点击查看:FLAG_ACTIVITY_CLEAR_TASK示例一的源码
我们修改"FLAG_ACTIVITY_NEW_TASK示例一"中onJump()函数,修改后的代码如下:
public void onJump(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
测试内容:ActivityTest --> SecondActivity --> ActivityTest --> SecondActivity
测试结果:(01) ActivityTest和SecondActivity在同一个task中! (02) 两个SecondActivity是不同的实例。
结果分析:这与没有添加FLAG_ACTIVITY_CLEAR_TASK时效果一样!这说明,当相互跳转的两个Activity的android:taskAffinity一样时,不会产生任何效果!
接下来,看看不同android:taskAffinity的情况。
3.2 FLAG_ACTIVITY_CLEAR_TASK示例二
点击查看:FLAG_ACTIVITY_CLEAR_TASK示例二的源码
我们修改"FLAG_ACTIVITY_NEW_TASK示例一"中onJump()函数,修改后的代码如下:
public void onJump(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
测试内容:ActivityTest --> SecondActivity --> ActivityTest --> SecondActivity --> 返回键 --> 返回键
测试结果:(01) ActivityTest和SecondActivity在不同的task中! (02) 两个SecondActivity是不同的实例。 (03) 第一次返回键,返回到第一个ActivityTest中。 (04) 第二次返回键,返回到进入第一个ActivityTest之前的画面。
结果分析:当同时使用FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TASK时,每次启动Activity时,若该Activity的实例已经存在于某个task中,则清除该task中的全部内容;然后重新创建task并将Activity添加到新建的task中;否则,直接启动新的task并将该Activity添加到新建的task中。
总的来说:FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TASK的使用和android:taskAffinity相关。在同时使用FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TASK的情况下,以A启动B来说
(01) 当A和B的taskAffinity相同时:添加FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TASK没有任何作用。和没有添加时的效果一样!
(02) 当A和B的taskAffinity不同时:添加FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TASK后,启动B时,若该B已经存在于某个task中,则清除该task中的全部内容;然后重新创建task并将B添加到新建的task中;否则,直接启动新的task并将B添加到新建的task中。
4. FLAG_ACTIVITY_SINGLE_TOP标签测试
FLAG_ACTIVITY_SINGLE_TOP的特性和launchMode="singleTop"一样!这里就不做过多的说明了。
点击查看:FLAG_ACTIVITY_SINGLE_TOP示例一的源码。该示例中,只有一个Activity示例,点击该Activity会跳转到它自身。
点击查看:FLAG_ACTIVITY_SINGLE_TOP示例二的源码。该示例中,有两个Activity示例,两个Activity之间可以相互跳转。
Android 之Activity启动模式(二)之 Intent的Flag属性的更多相关文章
- 关于Activity启动模式(launchMode)和intent设置测试后 发现和网上说的不符 是不是我错了 求解
看了很多关于Activity启动模式(launchMode)和intent设置intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);发现网上说的和我测试结果 ...
- Android中Activity启动模式详解
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...
- Android开发——Activity启动模式详解
1. Activity的启动模式 本文原创,转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52054893 1.1 Standard标 ...
- Android中Activity启动模式探索
Android中启动模式(launchMode)分为standard, singleTop, singleTask, singleInstance四种,可通过AndroidManifest.xml文件 ...
- 第二课android中activity启动模式
一.标准启动模式可以用函数gettaskid得到任务的idtostring得到地址用textallcaps来设置是否全部大写应用启动自己是在任务栈里创建不同实例可以用返回来返回上一个任务栈在andro ...
- android入门 — Activity启动模式
1.standard模式 standard模式是系统的默认启动方式,每次激活Activity都会创建Activity,并放在任务栈中. 系统不会在乎活动是否已经存在于返回栈中,每次启动都会创建该活动的 ...
- Android之Activity启动模式
正常模式 每个应用都有一个任务栈,任务栈中保存着已创建的Activity,先创建的Activity先入栈,栈顶是当前正在显示的activity(running),这是正常模式下的Activity的管理 ...
- Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();singleTask的两种启动方式。
原文:Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();singleTask的两种启动方式. Android Activity 的四种启动模 ...
- Android组件体系之Activity启动模式解析
本文主要分析Activity的启动模式及使用场景. 一.Activity启动模式浅析 1.standard 标准模式,系统默认的启动模式.在启动Activity时,系统总是创建一个新的Activity ...
随机推荐
- A*算法与8数字谜题(参见《算法》P226习题2.5.32)
A*算法的目的是找到一条从起始状态到最终状态的最短路径. 在A*算法中,需要在每个点计算启发函数:f(S) = g(S) + h(S),其中g(S)是从起点到S点的距离,h(S)是对从S点到终点的最短 ...
- zlog日志函数库
在C的世界里面没有特别好的日志函数库(就像JAVA里面的的log4j,或者C++的log4cxx).C程序员都喜欢用自己的轮子.printf就是个挺好的轮子,但没办法通过配置改变日志的格式或者输出文件 ...
- 【Hibernate】持久化对象状态及以及缓存
一.持久化类状态 1.1 三种持久化对象的状态 1.2 区分三种状态 1.3 三种状态对象转换 1.瞬时态 2.持久态 3.脱管态 4.持久态对象有自动更新数据库的能力 一.持久化类状态 1.1 三种 ...
- Java入门学习总结_02
一:注释 注释主要就是用来解释某句或者某段代码使得其他人调试更加方便.特点是在编译代码的时候不会编译注释, 不管发不发生错误.注释主要分为单行注释//(快捷键ctrl+/).多行注释/* */(快捷键 ...
- Viewer.js的inline模式
开始 前几天接到一个小的支持,要做一个有图像预览和操作功能的demo,并且给出了参照的模板.刚开始简单的看了一下给的模板,一个是boxImg.js,另一个是Viewer.js. 问题 其实图片预览的插 ...
- PAT Basic 1074 宇宙无敌加法器 (20 分)
地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的.而在 PAT 星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为“PAT数”.每个 PAT 星人都必须熟记各位数字的进制 ...
- 可能是最全面的 Python 字符串拼接总结
来源: 枫恋寒 链接: https://segmentfault.com/a/119000001.png"font-size: 12px;"> 在 Python 中字符串连接 ...
- python_反射:动态导入模块
官方推荐方法: test_mod.py def hi(): print('Hi') test.py import importlib q = importlib.import_module('test ...
- C#上传下载文件
方法一.通过Ajax方式上传文件(input file),使用FormData进行Ajax请求 <div > <input type="file" name=& ...
- python numpy的基本操作
站长资讯平台:文章目录0.NumPy 与 ndarry1.数组属性查看:类型.尺寸.形状.维度2.numpy元素中数据存储方式,数据类型,类型转换2.1 查看元素数据存储类型2.2 元素数据存储类型转 ...