Activity 四个启动模式和若干intent标记,应用场景。

standard
默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。

例如:
若我有一个Activity名为A1, 上面有一个按钮可跳转到A1。那么如果我点击按钮,便会新启一个Activity A1叠在刚才的A1之上,再点击,又会再新启一个在它之上……
点back键会依照栈顺序依次退出。

应用场景:
一般Activity没有特殊要求都是这种启动模式。

singleTop
可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。

例如:
若我有两个Activity名为B1,B2,两个Activity内容功能完全相同,都有两个按钮可以跳到B1或者B2,唯一不同的是B1为standard,B2为singleTop。
若我意图打开的顺序为B1->B2->B2,则实际打开的顺序为B1->B2(后一次意图打开B2,实际只调用了前一个的onNewIntent方法)
若我意图打开的顺序为B1->B2->B1->B2,则实际打开的顺序与意图的一致,为B1->B2->B1->B2。

应用场景:
比如收到推送消息,点击通知栏跳转到推送消息的详情页面,这个时候如果有多条相同类型的推送消息通知,用户点击之后多次跳转到那个消息详情页面,这个时候如果消息详情页面的Activity的启动模式是standard的话,就会一层层相同的Activity页面叠加在一起,用户可能就会困惑,所以这个时候我们就可以把那个详情页面Activity启动模式设置为singleTop,这样的话就只有一个Activity。

singleTask
只有一个实例。在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。
如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。

例如:
若我的应用程序中有三个Activity,C1,C2,C3,三个Activity可互相启动,其中C2为singleTask模式,
操作: C1->C2->C3->C2 最后实际存在的 C1->C2, C3已经被destroy掉了。

应用场景:
如果说一个应用需要被其他应用调起的时候,就可以把这个应用的首页的Activity设置为singleTask,这样其他应用调起的这个应用的首页的时候,就会把首页的上面的所有的Activity都destroy掉,如果首页不是singleTask,就会出现被其他应用调起的首页的时候,这时候用户点击返回可能不能返回到桌面,而是到了这个这个应用的其他页面(前提是这个应用在后台运行,没有被杀死)

singleInstance
只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。

例如:
程序有三个ActivityD1,D2,D3,三个Activity可互相启动,其中D2为singleInstance模式。那么程序从D1开始运行,假设D1的taskId为200,那么从D1启动D2时,D2会新启动一个task,即D2与D1不在一个task中运行。假设D2的taskId为201,再从D2启动D3时,D3的taskId为200,也就是说它被压到了D1启动的任务栈中。

应用场景:
这个一般比较少用到,那种非常公用的界面就会需要用到,比如说来电显示页面,闹钟响铃页面也可以用这个启动模式。

Intent几种常见的flags:

在android.content.Intent中定义了若干个flags,其中最重要的有以下几个:

1.FLAG_ACTIVITY_NEW_TASK:

当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的taskAffinity属性进行匹配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中,如果查找无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标Activity放置于此task。注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主

如果是用Context启动其他Activity,而不是是用Activity启动的话,如果没有加上这个标签就可能会有问题,异常如下:

02-10 17:13:20.448: ERROR/AndroidRuntime(5066): 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?

这个原因是:因为standard模式的Activity默认会进入启动它的Activity所属的任务栈中,但是由于非Activity类型的context(ApplicationContext)并没有所谓的任务栈,所以就出现问题了。需要指定Activity为FLAG_ACTIVITY_NEW_TASK标记位,这样启动的时候,就会为它创建一个新的任务栈了。

应用场景:
一般如果能确保一个Context就是Activity,通过这个Context来启动的另一个Activity就不要用这个启动方式,因为也许还会有问题,亲和力不强,导致不在同一个Task里面,一般通过service和广播来启动Activity就可以用这个方式。

待续….

猜你喜欢

转载自blog.csdn.net/HuangTieBing/article/details/73188322
今日推荐