Activity四种启动模式与Flag及affinity属性详解

时间:2021-10-01 18:48:15

Activity有四种加载模式:standard(默认)、singleTop、singleTask、singleInstance

standard:Activity的默认加载模式,即使某个Activity在Task栈中已经存在,另一个Activity通过Intent跳转到该Activity,同样会新创建一个实例压入栈中。

singleTop:例如,现在栈的情况是:A,B,C,D,D的Launch mode设置成了singleTop,那么在D中启动Intent跳转到D,那么将不会创建一个D实例压入栈中,此时栈的情况还是不变。而如果在此种情况下,在D实例中启动Intent跳转到B,则B会压入到栈中,此时的栈的情况变为:A、B、C、D、B。

singleTask:如果某个Activity设置成这个模式的话,则Task栈中只会有一个该Activity的实例。比如:现在栈的情况为A、B、C、D;而此时B的launch mode为singleTask,通过D跳转到B,则栈的情况为A、B。

singleInstance:将Activity压入一个新建的任务栈中。例如:Task栈1的情况为:A B C。C通过Intent跳转到D,而D的Launch mode为singleInstance,则将会新建一个Task栈2。此时Task栈1的情况还是为:A B C。Task栈2的情况为:D。此时屏幕界面显示D的内容,如果这时D又通过Intent跳转到D,则Task栈2中也不会新建一个D的实例,所以两个栈的情况也不会变化。而如果D跳转到C,则栈1的情况变成了:A B C C,因为C的Launch mode为standard,此时如果再按返回键,则栈1变成:A B C。也就是说现在界面还显示C的内容,不是D。

Intent的常用Flag参数:

FLAG_ACTIVITY_CLEAR_TOP:例如现在的栈情况为:A B C D 。D此时通过intent跳转到B,如果这个intent添加FLAG_ACTIVITY_CLEAR_TOP 标记,则栈情况变为:A B。如果没有添加这个标记,则栈情况将会变成:A B C D B。也就是说,如果添加了FLAG_ACTIVITY_CLEAR_TOP标记,并且目标Activity在栈中已经存在,则将会把位于该目标activity之上的activity从栈中弹出销毁。这跟上面把B的Launch mode设置成singleTask类似。

FLAG_ACTIVITY_NEW_TASK:例如现在栈1的情况是:A B C。C通过intent跳转到D,并且这个intent添加了FLAG_ACTIVITY_NEW_TASK 标记,如果D这个Activity在Manifest.xml中的声明中添加了Task affinity,并且和栈1的affinity不同,系统首先会查找有没有和D的Task affinity相同的task栈存在,如果有存在,将D压入那个栈,如果不存在则会新建一个D的affinity的栈将其压入。如果D的Task affinity默认没有设置,或者和栈1的affinity相同,则会把其压入栈1,变成:A B C D,这样就和不加FLAG_ACTIVITY_NEW_TASK 标记效果是一样的了。      注意如果试图从非activity的非正常途径启动一个activity,比如从一个service中启动一个activity,则intent比如要添加FLAG_ACTIVITY_NEW_TASK 标记。

FLAG_ACTIVITY_NO_HISTORY:不加入task栈中,不缓存,跳到其他界面时销毁activity实例,回掉onDestroy。例如现在栈情况为:A B C。C通过intent跳转到D,这个intent添加FLAG_ACTIVITY_NO_HISTORY标志,则此时界面显示D的内容,但是它并不会压入栈中。如果按返回键,返回到C,栈的情况还是:A B C。如果此时D中又跳转到E,栈的情况变为:A B C E,此时按返回键会回到C,因为D根本就没有被压入栈中,且从D跳到E之后或从D返回C后,D的实例就被销毁了,会回调onDestroy。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS(excludeFromRecents="true"):新启动的actiivty所属的task栈不添加到最近应用列表中,也即我们从最近应用(长按HOME键或处于桌面时按MENU键)里面查看不到我们启动的这个activity。不过目前不同手机厂商做了不同的优化,最近应用列表不一定是以还存在activity的task栈的个数显示,而是以还存在activity的app的个数显示。所以这个FLAG很不常用,注意和FLAG_ACTIVITY_NO_HISTORY区分开,这两个标识含义不一样。

FLAG_ACTIVITY_SINGLE_TOP:和上面Activity的 Launch mode的singleTop类似。如果某个intent添加了这个标志,并且这个intent的目标activity就是栈顶的activity,那么将不会新建一个实例压入栈中。

Activity的taskAffinity属性:

每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该 Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果 Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根 Activity的taskAffinity的值。

Activity的allowTaskReparenting属性:

这个属性用来标记一个Activity实例在当前应用退居后台后,是否能从启动它的那个task移动到有共同affinity的task,“true”表示可以移动,“false”表示它必须呆在当前应用的task中,默认值为false。例如在一个应用中要查看一个web页面,在启动系统浏览器Activity(假设启动模式不是singleInstance,但拥有自己的taskAffinity)后,这个Activity实例和当前应用处于同一个task,当我们的应用退居后台之后用户再次从主选单中启动应用,此时这个Activity实例将会重新宿主到Browser应用的task内,在我们的应用中将不会再看到这个Activity实例,而如果此时启动Browser应用,就会发现,第一个界面就是我们刚才打开的web页面,证明了这个Activity实例确实是宿主到了Browser应用的task内。

Activity的其它主要属性:

alwaysRetainTaskStat:   如果用户长时间将某个task 移入后台,则系统会将该task的栈内容弹出只剩下栈底的activity,此时用户再返回,则只能看到根activity了。如果栈底的 activity的这个属性设置成true,则将阻止这一行为,从而保留所有的栈内容。

clearTaskOnLaunch:根activity的这个属性设置成true时,和上面的alwaysRetainTaskStat 的属性为true情况搞好相反。

finishOnTaskLaunch:对于任何activity,如果它的这个属性设置成true,则当task被放置到后台,然后重新启动后,该activity将不存在了。

其它一些说明

(1)使用场景

singleInstance 比如:启动一个activity让用户填资料,填完后转到主activity;或启动相册选择照片、启动相机拍照,完成后跳到下一个流程activity;此时按后退,不可以再退回填资料、选照片或拍照的界面,而应该是之前的activity。此时中间的activity适合使用singleInstance。还有调起通话和接听来电界面

singleTask:app首页可使用,进入首页时清空之前的历史界面activity

(2)LaunchMode与taskAffinity属性结合

每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task栈。如果一个Activity没有显式的指明该Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果 Application也没有指明,那么该taskAffinity的值就等于包名。而Task栈也有自己的affinity属性,它的值等于它的根Activity的taskAffinity的值。且两个Task栈可以是相同的taskAffinity属性(比如LaunchMode为singleInstance时,会在新的task栈中创建activity实例,此时两个task栈taskAffinity属性是相同的,默认都是包名)

(3)singleTask与taskAffinity结合时:

当一个应用程序加载一个singleTask模式的Activity时,首先会检查是否存在与该Activity相同taskAffinity属性的Task栈。

1、若存在,再检查Task栈中是否已存在该Activity的实例,如果已存在,那么销毁在该Activity以上的Activity并调用onNewIntent。如果不存在,那么将新建该Activity的实例入栈。

2、若不存在,那么就新创建taskAffinity属性的Task栈,并新建该Activity的实例入栈。

(4)singleInstance与taskAffinity结合时:

1、当启动一个singleInstance模式的Activity时,在所有Task栈中若不存在该Activity的实例,那么就重新创建一个Task栈,并新建该Activity的实例入栈;若存在,则重用该Activity实例,回调其onNewIntent;

2、singleInstance的Activity所在的Task栈不允许存在其他Activity,任何从该Activity加载的其它 Actiivty(假设为Activity2)都会被放入其它Task栈中;若Activity2 LaunchMode不是singleInstance,则判断是否存在与Activity2相同affinity的Task栈,存在就在该Task栈内创建Activity2,不存在,则重新生成新的Task栈并入栈。若Activity2 LaunchMode也是singleInstance,则就是前面1所述的流程——比如一个singleInstance模式的Activity启动自己,则不会新创建Task栈,也不会新创建Activity实例,而是复用自己的实例,回调onNewIntent

(5)CLEAR_TOP与各种Activity启动模式连用:

https://blog.csdn.net/yztbydh/article/details/80450615

其它参考:

http://www.cnblogs.com/meizixiong/archive/2013/07/03/3170591.html

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0520/2897.html

http://blog.csdn.net/u012778718/article/details/53410199  : activity中与taskAffinity,allowTaskReparenting,启动模式相关的问题

http://blog.csdn.net/zhangjg_blog/article/details/10923643

Activity四种启动模式与Flag及affinity属性详解的更多相关文章

  1. Android Activity 四种启动模式

    task和back stack(任务和回退栈) 任务启动,task被加入到回退栈的栈顶,返回的时候回退栈的栈顶任务会被弹出,并被销毁,栈中的前一任务恢复运行,当activity销毁是,系统不会保留ac ...

  2. 简单易懂的Activity四种启动模式

    Activity的四种启动模式 我们在项目开发的过程中,会涉及到应用中各个Activity的跳转,有些Activity是可以复用,不用重复加载,节约内存的使用. 将第二个Activity的启动模式修改 ...

  3. Activity四种启动模式之singleTask应用

    Activity启动模式设置:         <activity android:name=".MainActivity" android:launchMode=&quot ...

  4. Android -- Activity的生命周期,Activity四种启动模式 Standard&comma; SingleTop&comma;SingleTask&comma;SingleInstance

    1. 示例图 . 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环:  Activity的完整生命周期自第一次调用onCreate()开始,直至调 ...

  5. android&colon;Activity四种启动模式简单介绍

    Activity启动模式 能够依据实际的需求为Activity设置相应的启动模式,从而能够避免创建大量反复的Activity等问题 Activity有四种载入模式 1.standard(默认启动模式, ...

  6. Activity四种启动模式

    转载博客:http://blog.csdn.net/shinay/article/details/7898492 Activity启动方式有四种,分别是:standardsingleTopsingle ...

  7. activity 四种启动模式

    前言 Activity的启动模式决定了Activity的启动运行方式 四种模式 Activity启动模式设置: <activity android:name=".MainActivit ...

  8. Android中的Activity四种启动模式&lpar;launchMode&rpar;

    转载:http://blog.csdn.net/cjjky/article/details/7533110          我们在开发项目的过程中,会涉及到该应用中多个Activity组件之间的跳转 ...

  9. Android入门:Activity四种启动模式

    一.启动模式介绍 启动模式简单地说就是Activity启动时的策略,在AndroidManifest.xml中的标签的android:launchMode属性设置: 启动模式有4种,分别为standa ...

随机推荐

  1. 【Android】一道Android OpenGL笔试题

    一道Android OpenGL笔试题 SkySeraph May. 5th 2016 Email:skyseraph00@163.com 更多精彩请直接访问SkySeraph个人站点:www.sky ...

  2. nginx 配置&period;json文件直接访问

    不要弹出下载 配置nginx.conf http { include mime.types; default_type application/json;

  3. 用 Javascript 获取页面大小、窗口大小和滚动条位置

    页面大小.窗口大小和滚动条位置这三个数值在不同的浏览器例如 Firefox 和 IE 中有着不同的实现.即使在同一种浏览器例如 IE 中,不同版本也有不同的实现. 本文给出两个能兼容目前所有浏览器的 ...

  4. 定位 - MapKit-自定义大头针

    #import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface PPAnnotation : NS ...

  5. Automatically generate serial number in abap

    流水号的产生:   在ABAP开发中,很多地方都需要按照自己的规则生成流水号,把这些流水号保存进透明表,作为唯一标示. 一. 系统中设定流水号 使用T-Code SNRO来创建一个流水号标识对象. 输 ...

  6. Laravel 开发环境搭建 - Windows

    Laravel 开发环境搭建 - Windows  :   https://laravel-china.org/docs/laravel-development-environment/5.5/dev ...

  7. JS检测是否是360浏览器

    // JavaScript Document //application/vnd.chromium.remoting-viewer 可能为360特有 var is360 = _mime("t ...

  8. Apache cxf暴露接口以及客户端调用之WebService初步理解

    在我们真实的项目中,经常会调用别人提供给我们的接口,或者在自己的团队中, restful风格的前后端分离也经常会提供一个后端接口暴露出去供app,或者.net/C/C++程序员去调用,此时就需要使用到 ...

  9. Excel核心技巧【干货】

    进入职场后发现,几乎有很大一部分时间都耗在了表格上. Excel的存在是为了更高效工作,但庞大的数据处理却成了你每晚加班的“凶手”? 其实,从数据整理到数据分析,只要掌握20%的Excel技巧,就足以 ...

  10. JS jQuery json日期格式问题的办法

    原生JS:Date对象详细参考 Date对象:基于1970年1月1日(世界标准时间)起的毫秒数 本文参考MDN做的详细整理,方便大家参考MDN 构造函数: new Date(); 依据系统设置的当前时 ...