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叠加。即,假设Activity在栈顶的时候,启动同样的Activity,不会创建新的实例,而会调用其onNewIntent方法。

比如:
若我有两个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。

作用:避免一个糟糕的用户体验,假设这个界面已经被打开且在任务栈的栈顶,就不会反复开启了

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->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的实例,有线程安全问题!

比如闹铃提醒,将闹铃提醒与闹铃设置分离


posted on 2017-08-03 17:46  ljbguanli  阅读(156)  评论(0编辑  收藏  举报