一.启动模式:
1.Standard
- 默认是standard模式
- A启动B,B就会进入A所在的任务栈中
- 不管要启动的activity在任务栈中是否存在,都会重新创建一个新的实例
- 在Activity A中不断的启动自己
android:launchMode="standard"
MainActivity-->com.code.MainActivity@2cdaf713-->栈:885
MainActivity-->com.code.MainActivity@2d2219ca-->栈:885
MainActivity-->com.code.MainActivity@177c5ca6-->栈:885
2.SingleTop
- A启动B,B就会进入A所在的任务栈中
- 要启动的Activity如果处于栈顶,不会创建新的实例,而会调用onNewIntent()方法;如果不在栈顶,则会创建新的实例;
- B的启动方式是SingleTop,A中启动B,在B中再启动B
android:launchMode="singleTop"
A:MainActivity-->com.code.MainActivity@2cdaf713-->栈:887
B:onCreate-->com.code.BActivity@2d2219ca-->栈:887
B:onNewIntent-->com.code.BActivity@2d2219ca-->栈:887
B:onNewIntent-->com.code.BActivity@2d2219ca-->栈:887
3.SingleTask
- 启动A,会先看是否存在A想要的任务栈,不存在,创建任务栈,把A放进去;存在,判断是否存在A的实例,存在,则会调用onNewIntent(),默认具有clearTop的效果,会清空它上面的所有activity,让它们出栈,并将要启动的activity置于栈顶;否则会创建新的实例;
- B的启动模式是SingleTask,A启动B,B启动C,C中再启动B
android:launchMode="singleTask"
A:MainActivity-->com.code.MainActivity@2cdaf713-->栈:889
B:onCreate-->com.code.BActivity@2d2219ca-->栈:889
C:onCreate-->com.code.CActivity@1490bfe8-->栈:889
B:onNewIntent-->com.code.BActivity@2d2219ca-->栈:889
4.SingleInstance
- A启动B,B会进入一个新的任务栈中
- SingleInstance是SingTask的升级版,它具有SingleInstance的所有特性,要启动的Activity会在一个新的任务栈中创建,如果之后要再启动这个Activity,先看任务栈中是否存在这个Activity,存在,调用onNewIntant(),并将上面的Activity清空;否则创建一个新的实例;
- B的启动模式是SingleInstance,A启动B后,B再启动B
android:launchMode="singleInstance"
A:MainActivity-->com.code.MainActivity@2cdaf713-->栈:892
B:onCreate-->com.code.BActivity@2d2219ca-->栈:893
B:onNewIntent-->com.code.BActivity@2d2219ca-->栈:893
注意
getApplication().startActivity(new Intent(this,BActivity.class));
如果这样启动一个Activity,会报错:
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
之前在项目中,来电时会出一个Activity,就报了这个错,这个错是什么原因导致的呢?
因为getApplication()是非Activity类型的context,并不存在任务栈一说,所以启动B的时候,B会添加到getApplication()所在的任务栈,这就矛盾了,这时候并不存在任务栈,所以只能将B添加到一个新的任务栈中
任务栈
- 分为前台任务栈和后台任务栈
- 在SingleTask中多次提到了任务栈,那么什么是任务栈呢?
这里涉及到一个名词“TaskAffinity”,可以叫“任务相关性”,它是任务栈的名字,所有Activity都默认是包名。 -
TaskAffinity只有和"SingleTask"
或者“allowTaskReparenting”一起使用时才起作用,如果TaskAffinity指定为当前包名,也是无效的,因为默认就是包名,没啥用处。 - TaskAffinity和"SingleTask"一起使用
<activity
android:name=".BActivity"
android:launchMode="singleTask"
android:taskAffinity="com.app.b"/>
也就是所有taskAffinity相同的会在一个任务栈中存在;
-
TaskAffinity和"allowTaskReparenting"一起使用, app A启动了 app B的 Activity C(allowTaskReparenting为true),这时候启动app B了,那么在B上显示的是哪一个页面呢?
答案是Activity C。
分析:
A启动了页面c,这时候c的TaskAffinity和A的TaskAffinity肯定不同,但是又没有c所需要的任务栈存在,所以c只能现在A的任务栈中运行,这时候B打开了,系统发现c所需要的任务栈存在了,就会将c移到B的任务栈中,所以会看到B上显示的是c页面。 -
A,B,C三个Activity,B和C的TaskAffinity为com.app.task,启动模式为SingleTask;A启动B后,B启动C,C再启动A后,A启动B后,点击back点击显示谁?
分析:
①定义两个任务栈S1和S2
②A和B的TaskAffinity不同,A启动B的时候,不存在名为"com.app.task"的任务栈,所以创建一个新的任务栈S2;
③B启动C,他们的TaskAffinity相同,任务栈已存在,将C直接入栈,置于B的上面;
④C启动A,A的启动模式是standard,会在S2中入栈;
⑤A启动B,这时候要启动的B在S2中已经存在了,就将它上面的CA全部出栈,S2中只剩下B;
⑥再点Back键,B出栈,直接返回桌面,因为这时候最开始A所在的S1任务栈是后台栈;这时候后台任务栈就变成前台任务栈了,A显示,再次点击back键,返回桌面;
通过Intent标志位指定启动模式
-
和manifest中设置有什么区别?
manifest中无法设置Intent.FLAG_ACTIVITY_CLEAR_TOP;
Intent方式无法设置SingleInstance; -
常用的几个:
①这个和在xml中的效果是一样的,singleTop
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
②这个和在xml中的效果是一样的,singleTask
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
③这个表示将上面的activity都清空出栈,一般和②搭配使用,如果要启动的activity存在,则调用onNewIntent(),清空它上面的activity;如果要启动的activity是standard模式,则它会连同它上面的activity一块清空,然后创建新的实例;
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
④这个表示将要启动的activity不会添加到历史activity中,和在xml中加入android:excludeFromRecents="true"效果一样
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Intent-filter匹配规则
![](https://img.haomeiwen.com/i1340588/4bd3a94509c9a129.png)
网友评论