Android Activity的launchMode

来源:互联网 发布:w两个世界知乎 编辑:程序博客网 时间:2024/04/30 19:35

今天公司没事,看了一下launchMode的内容,找到几篇文章,感觉讲的很好所以就修改了一些组合在一起,方便以后复习。

1. Task

原文:http://blog.csdn.net/linmiansheng/article/details/24236671

了解launcMode之前,有必要简单了解一下Task的知识。Android中Task是一个逻辑上的概念,简单地说,就是一个栈里面顺序存储着的多个Activity。这些Activity可以是来自同一个App,也可以是来自不同的Apps。

Taks的创建

比如一个List列表的Demo,当它被安装到手机上之后,在应用程序列表,也即Launcher中,会有一个图标显示,如果长按这个图标,还能为其在桌面上创建一个快捷方式。

当点击这个图标,或者快捷方式,List中入口的Main Activity就会被创建,而与此同时,一个Stack也会被创建,然后,Activity会被放到这个Stack中。
当Main Activity,点击列表项,Detail Activity会创建,也被放到Stack中。
当在Detail Activity中点击“查看图片”进入Image Activity,Image Activity也被放入Stack中,
而当Image Activity,通过Intent,调用系统中另外一个App(照相机)去获取照片时,它调用的其实是照相机App中的一个Activity,在默认这个情况下,这个Activity也是被放在当前的Stack中。

上面的这个流程如下图所示:


这样的一系列Activity的顺序组合,在Android中的概念就是一个Task。通俗地说,它表示了一个App顺序提供的功能展示,包括其调用其他App的功能。

Task的结束

而当用户点击Back键,或者ActionBar上的返回键的时候,当前的Activity就会从Stack中被弹出来,然后销毁,这样一直返回,最后最开始的Activity,在上例中是
Main Activty,也会被从stack中弹出来,并消毁,而结果就是回到桌面上,当最后一个Activity从stack中退出的时候,stack也被销毁了,那么一个Task也就没有存在的意义了。

那么此时就不存在Task了。

Task的切换

所以从Launcher中或者快捷方式启动一个App的时候,如果这个App最近没有被启动过,那么就会创建一个新的Stack,从而启动一个新的Task。
Home应用,也是一个Task,当用户点击Home键的时候,屏幕就会跑到桌面,也就是说,当前的Task被停止了,而切换到了Home所在的Task。
此时,原来显示在屏幕上的Task就会被转移到后台,在用户看不见的屏幕的深处,在那里,Task中的所有Activity都会处于stop状态,但是所有的内容和状态都会被保存。
当从Launcher中,或者快捷方式,再去点击应用的图标的时候,处于后台的Task又会被带到屏幕上显示,用户可以继续操作,而Home应用所在的Task就被切换到后台。
所以在用户看着屏幕的时候,在屏幕后面那些不可见的虚拟空间中,可能同时存在着多个Task,静静地呆着,等待着随时被带到屏幕上展示。

上面所述的处理,都是在Android中默认的情况下发生的。在这种情况下,当创建一个Activity,就会往Stack中放一个Activity,当返回上一个Activity,当前的Activity就会被移除
并消毁,而Task可以同时存在多个相同的Activity。

当然,Android也提供了一些属性或者标志来让用户去修改默认的处理行为,其中一个就是使用launchMode。

2. LaunchMode

原文:http://blog.csdn.net/shinay/article/details/7898492

原文:http://www.eoeandroid.com/blog-531377-3446.html

在Android的中Activity有4种启动方式:"standard"、"singleTop"、"singleTask"、"singleInstance"。

可以根据实际的需求为Activity设置对应的启动模式,从而可以避免创建大量重复的Activity等问题。
设置Activity的启动模式,只需要在AndroidManifest.xml里对应的<activity>标签设置android:launchMode属性,例如:

[html] view plaincopy
  1. <activity   android:name=".A1" android:launchMode="standard" />  
下面是这四种模式的作用:

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

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

singleTop
可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在Task栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent()方法(singleTop的意思就可理解为,同一个Activity栈顶不允许出现重复)如果调用的Activity不在Task栈顶,系统此时调用方式与standard方式下的一模一样。

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


singleTask
在同一个应用程序中启动他的时候,若Activity不存在,则会在当前Task创建一个新的实例,若存在,则会把Task中在其之上的其它Activity destory掉并调用它的onNewIntent()方法。(也就是说singleTask的意思是该Activity只允许存在于一个Task中)。
如果是在别的应用程序中启动它,则会新建一个Task,并在该Task中启动这个Activity,singleTask允许别的Activity与其在同一个Task中共存,这点与下面说的singleInstance不同,也就是说,如果我在这个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。
注意:假如你启动一个singleTask的Activity时,这个Activity恰好在后台的某个Task中,那么这整个后台的Task都会被调入到前台来。下面这幅图就很好的说明这个问题。

ActivityY 使用singleTas的模式,当位于蓝色Task的Activity2启动ActivY时,绿色Task整个被调到前台。这时如果按返回键,ActivityY退出,ActivityX出现。再按一次返回键,ActivityX退出,整个绿色Task结束,蓝色Task的Activity2出现。


singleInstance


只有一个实例,并且这个实例独立运行在一个Task中,这个Task有且只有这个Activity实例,不允许有别的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了。


另外,在代码中通过StartActivity来启动下一个Activity的时候,可以通过设置Intent的Flag来修改默认的Task管理标志,如下:
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Flag的值有以下三个:

FLAG_ACTIVITY_NEW_TASK 
    这个值跟LaunchMode中的SingleTask的效果是一样的。

FLAG_ACTIVITY_SINGLE_TOP
    这个值跟LaunchMode中的SingleTop的效果是一样的。

FLAG_ACTIVITY_CLEAR_TOP

    当Intent设置了这样一个标志,那么Android就会去寻找一个存在的Activity,如果找到了,其上面存在有其他Activity的话,就会将其上面的所有Activity都清除掉。


最后,其实Activity的launchMode还往往和taskAffinity组合使用,这个之后再研究一下。

0 0
原创粉丝点击