Android--Activity四种启动模式
launchMode在多个Activity跳转的过程中扮演着重要的角色,它能够决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其它Activity实例公用一个task里。这里简介一下task的概念,task是一个具有栈结构的对象。一个task能够管理多个Activity,启动一个应用,也就创建一个与之相应的task。
Activity一共同拥有下面四种launchMode:
1.standard
2.singleTop
3.singleTask
4.singleInstance
我们能够在AndroidManifest.xml配置<activity>的android:launchMode属性为以上四种之中的一个就可以。
<pre name="code" class="html" style="font-size: 14px;"><activity android:name=".A1" android:launchMode="standard" />standard
默认模式,能够不用写配置。
在这个模式下,都会默认创建一个新的实例。因此。在这样的模式下。能够有多个同样的实例,也同意多个同样Activity叠加。
比如:
若我有一个Activity名为A1, 上面有一个button可跳转到A1。那么假设我点击button,便会新启一个Activity A1叠在刚才的A1之上,再点击,又会再新启一个在它之上……
点back键会按照栈顺序依次退出。
singleTop
比如:
若我有两个Activity名为B1,B2,两个Activity内容功能全然同样。都有两个button能够跳到B1或者B2。唯一不同的是B1为standard,B2为singleTop。
若我意图打开的顺序为B1->B2->B2,则实际打开的顺序为B1->B2(后一次意图打开B2。实际仅仅调用了前一个的onNewIntent方法)
若我意图打开的顺序为B1->B2->B1->B2,则实际打开的顺序与意图的一致,为B1->B2->B1->B2。
作用:避免一个糟糕的用户体验,假设这个界面已经被打开且在任务栈的栈顶,就不会反复开启了
假设是在别的应用程序中启动它,则会新建一个task。并在该task中启动这个Activity。singleTask同意别的Activity与其在一个task中共存,也就是说,假设我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。
比如:
若我的应用程序中有三个Activity,C1,C2,C3,三个Activity可互相启动,当中C2为singleTask模式,那么,不管我在这个程序中怎样点击启动,如:C1->C2->C3->C2->C3->C1-C2,C1,C3可能存在多个实例,可是C2仅仅会存在一个。而且这三个Activity都在同一个task里面。
可是C1->C2->C3->C2->C3->C1-C2,这种操作过程实际应该是例如以下这种,由于singleTask会把task中在其之上的其他Activity destory掉。
操作:C1->C2 C1->C2->C3 C1->C2->C3->C2 C1->C2->C3->C2->C3->C1 C1->C2->C3->C2->C3->C1-C2
实际:C1->C2 C1->C2->C3 C1->C2 C1->C2->C3->C1 C1->C2
若是别的应用程序打开C2,则会新启一个task。
如别的应用Other中有一个activity,taskId为200。从它打开C2。则C2的taskIdI不会为200,比如C2的taskId为201,那么再从C2打开C1、C3。则C2、C3的taskId仍为201。
注意:假设此时你点击home,然后再打开Other,发现这时显示的肯定会是Other应用中的内容。而不会是我们应用中的C1 C2 C3中的当中一个。
应用场景:
浏览器:底层使用的是webkit c 内核,初始化一次须要申请非常多的内存资源,占用cpu时间。所以使用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启动的任务栈中。
若是在别的应用程序打开D2,如果Other的taskId为200,打开D2。D2会新建一个task执行,如果它的taskId为201,那么如果这时再从D2启动D1或者D3,则又会再创建一个task,因此,若操作步骤为other->D2->D1,这过程就涉及到了3个task了。
特点:
singleInstance的启动模式更加极端,
开启新的activity,会给自己创建一个单独的任务栈
无论是从应用内部打开还是通过其它应用调用
TaskId是单独的。已存在的则仅仅需调用onNewIntent
应用场景:
在整个手机操作系统里面仅仅会有一个该activity的实例存在,
有道词典,金山词典
所以多个应用程序共享这个activity的实例,有线程安全问题!
比如闹铃提醒,将闹铃提醒与闹铃设置分离