Activity一共有以下四种launchMode:
1.standard
2.singleTop
3.singleTask
4.singleInstance
作用概述:规定是否新建activity,是否公用task(task:应用启动时,会创建一个对应的task。task主要负责对activity进行管理。)
使用方法:我们可以在AndroidManifest.xml配置
第一种模式:standard
这是系统默认的启动模式,即:不用再在AndroidManifest.xml配置
作用:标准模式下,只要用intent 跳转,系统会自动创建一个新的activity实例,并且放在栈顶。按下回退键,系统会从顶部开始一个一个清除Activity。
第二种模式:singleTop
作用:singleTop模式下,如果要跳转的activity的实例已经在栈中存在,看其是否位于栈顶,如果位于栈顶,则直接启用旧的,不在创建实例,如果不在栈顶,则创建一个新的实例。
第三种模式:singleTask
作用:如果要启动的activity的实例不存在,则创建一个新的实例。如果要启动activity的实例在栈中已经存在,则清除此activty旧实例以上的所有activity,启动旧activity的实例并且至于栈顶,开始执行OnResum()方法。
问题:启动模式为singletask,activity无法获取到intent的传值问题。
原因:
1.启动一个为启动过的activity ,会获取到新的 intent。也就是说就是启动模式设置为:singletask,第一次启动界面是传递的数据是可以接受到的。
2.当此界面再次被启动时,因为他的启动模式是:singletask,所以不会重新创建一个activity,而是启动旧的activity实例,通过getIntent()方法获取到的 intent 也是旧的Intent,没有携带新的数据。所以无法获取到数据。
解决方法:重写这个方法,并且把调用setIntent(intent),对Intent进行更新。此方法在activity(启动模式为:singletask)的界面第二次启动时,在onresume()方法之前被回调。
@Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
setIntent(intent);
}
第四种模式:singleInstance
作用:系统会重新启用一个栈,并且把这个activity放入新的栈中,并且保证不会再让其他的activity进入。再次跳转该activity,activity如果存在则直接启用,不存在创建新的。
注意:5.0以上的部分手机,一个应用存在多个栈的情况下,切到后台,后台会出现多个后台同一个应用的界面,这是因为界面不在同一个栈中。
Activity栈(Task)的相关知识总结:
1.Activity的affinity(亲和力)
2.Intent几种常见的flags
3.
第一个: Affinity(密切关系)
在系统默认情况下,打开一个app,系统默认包名为affinity的值。task自身的affinity的值取决于根activity的affinity。具有相同的affinity的activity同属于一个task。
实例1:
建立两个demo App分别命名为 A 和 B。从 A 的主界面通过意图跳转到 B 的主界面界面。此时两个app的界面位于同一个App A的栈内。如图:
第二个: Intent 常用的 flag:
1.FLAG_ACTIVITY_NEW_TASK 根据Activity 的 affinity去寻找task 栈。如果一个task 的 affinity与 activity 的 affinity的相同,则 Activity会压入栈中。如果没有找到相同的,则新建立栈,并且把activity压入栈中。
实例1: 从App A主界面跳转到 App B主界面。给Intent添加FLAG_ACTIVITY_NEW_TASK 标识。
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
结果会建立两个栈。App A 的界面在App A 的栈里。App B 的界面在 App B 的栈里边。
实例2:在实例1 的基础上,在App B里添加代码,给App B的主界面 在manifest 中添加
android:label="@string/app_name" >
com.example.a为App A 的包名。这样的结果是 App A 和App B的界面会在同一个栈里。
2.FLAG_ACTIVITY_CLEAR_TOP 检查栈内是否存在要启动的Activity实例,如果存在实例,则会调用旧的Activity实例,并且清除此Activty 上面的所有的activty,使其至于栈顶显示出来。
注意:1. intnet.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 跳转的页面会从 OnCreate()方法开始执行。
2.FLAG_ACTIVITY_CLEAR_TOP 相当于 加载模式的 signleTask
3.FLAG_ACTIVITY_SINGLE_TOP 相当于加载模式的 signleTop
4.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 如果Intent 包含此属性,那么,要跳转的activity和次activity上的所有界面,都会在task重置时被清除。(待定)
5.FLAG_ACTIVITY_NO_HISTORY 如果Intent 包含此属性,那么,要启动activity 将显示一次,不会再task栈内保存。
6.FLAG_ACTIVITY_REORDER_TO_FRONT 把已经存在的界面拿到栈顶,
例:ABCD已经存在,D通过FLAG_ACTIVITY_REORDER_TO_FRONT 去启动A,则栈内顺序BCDA。
7.FLAG_ACTIVITY_BROUGHT_TO_FRONT(测试不起作用)