文档章节

Activity启动模式

robertchao
 robertchao
发布于 2016/05/20 13:21
字数 2127
阅读 1
收藏 0

当应用运行起来后就会开启一条线程,线程中会运行一个任务栈,当Activity实例创建后就会放入任务栈中。Activity启动模式的设置在AndroidManifest.xml文件中,通过配置Activity的属性android:launchMode=""设置。


1. Standard模式(默认)
我们平时直接创建的Activity都是这种模式的Activity,这种模式的Activity的特点是:只要你创建了Activity实例,一旦激活该Activity,则会向任务栈中加入新创建的实例,退出Activity则会在任务栈中销毁该实例。
standard模式是所启动的Activity都是在同一个task容器栈下,不会重新创建新的task容器栈。先压入栈的Activity实例按顺序入栈底,后入栈在栈顶,处于栈的顶部Activity实例处于活动状态,其他处于非活动状态。按物理返回键,退出当前所处活动状态Activity窗口,这样就会从task容器栈中弹出,显示在手机主屏幕上,从而,有非活动状态转换成活动的状态。其次,standard容器栈可能会存在着相同的Activity实例,只有没调用一次startActivity方法,就会创建目标Activity实例对象压入task容器栈。
如果Activity启动顺序为A->B->B->A->D,栈中的Acitivy为ABBAD(最先创建的A位于栈底,最后创建的D位于栈顶)


2. SingleTop模式
这种模式会考虑当前要激活的Activity实例在任务栈中是否正处于栈顶,如果处于栈顶则无需重新创建新的实例,会重用已存在的实例,否则会在任务栈中创建新的实例。
SingleTop有个不错的用法是防止多次点击创建多个Activity,无论start几次,SingleTop模式能保证栈顶只有一个实例。 如果Activity启动顺序为A->B->B->A->D,栈中的Acitivy为ABAD(当B位于栈顶时,再次启动B的时候,B不会重新创建)


3. SingleTask模式
如果任务栈中存在该模式的Activity实例,则把栈中该实例以上的Activity实例全部移除,调用该实例的newInstance()方法重用该Activity,使该实例处於栈顶位置,否则就重新创建一个新的Activity实例。
singletask模式,特别需要注意了。启动的目标Activity实例如果已经存在task容器栈中,不管当前实例处于栈的任何位置,是栈顶也好,栈底也好,还是处于栈中间,只要目标Activity实例处于task容器栈中,都可以重用该Activity实例对象,然后,把处于该Activity实例对象上面全部Activity实例清除掉,并且,task容器栈中永远只有唯一实例对象,不会存在两个相同的实例对象。所以,如果你想你的应用不管怎么启动目标Activity,都只有唯一一个实例对象,就使用这种启动模式。 如果Activity启动顺序为A->B->B->A->D,栈中的Acitivy为AD(当A再次被启动时,A会被移到栈顶,位于A上面的Acitivity全部会出栈)


4. SingleInstance模式
当该模式Activity实例在任务栈中创建后,只要该实例还在任务栈中,即只要激活的是该类型的Activity,都会通过调用实例的newInstance()方法重用该Activity,此时使用的都是同一个Activity实例,它都会处于任务栈的栈顶。此模式一般用于加载较慢的,比较耗性能且不需要每次都重新创建的Activity。
singleInstance启动模式,简单说就是可以共享某个Activity。比如,应用1的任务容器栈中创建了MainActivity实例,应用2也要激活MainActivity,则不需要创建MainActivity实例,直接可以公用MainActivity实例。 尤其值得注意:应用1启动MainActivity,按home键;打开应用2启动应用1的MainActivity实例。在按home键,打开应用1,这时候应用1的界面是应该是处于MainActivity界面实例。 SingleInstance的一个任务栈中只有一个Activity,并保证不再有其他Activity实例进入。


特别需要注意的生命周期onNewIntent
当一个Activity被start,而不需要重新创建时,就会执行onNewIntent生命周期。如果一个Activity的启动模式是SingleTask,我们可以在onNewIntent中执行一些刷新操作等。
我们一般会把MainAcitivy设置为SingleTask,除了保证MainActivity的唯一,还可以利用singleTask的特性做一些清理工作。自动管理栈,销毁无用的Acitivity.


Intent Flags 
Flags: 表示Intent的标志位,常用于Activity的场景中,它和Activity的启动模式有着密切的联系。
下面列举的是和本文主题相关的Flags属性:
Intent.FLAG_ACTIVITY_NEW_TASK (默认)
默认的跳转类型,它会重新创建一个新的Activity,不过与这种情况,比如说Task1中有A,B,C三个Activity,此时在C中启动D的话,如果在AndroidManifest.xml文件中给D添加了Affinity的值和Task中的不一样的话,则会在新标记的Affinity所存在的Task中压入这个Activity。如果是默认的或者指定的Affinity和Task一样的话,就和标准模式一样了启动一个新的Activity.

FLAG_ACTIVITY_SINGLE_TOP
这个FLAG就相当于启动模式中的singletop,例如:原来栈中结构是A B C D,在D中启动D,栈中的情况还是A,B,C,D。

FLAG_ACTIVITY_CLEAR_TOP
这个FLAG就相当于启动模式中的SingleTask,这种FLAG启动的Activity会把要启动的Activity之上的Activity全部弹出栈空间。例如:原来栈中的结构是A B C D ,从D中跳转到B,栈中的结构就变为了A B了。(这个方法可以用来关闭多个Activity,之后的一篇博文里面会提到)

FLAG_ACTIVITY_BROUGHT_TO_FRONT
这个网上很多人是这样写的。如果activity在task存在,拿到最顶端,不会启动新的Activity。这个有可能会误导大家! 他这个FLAG其实是这个意思!比如说我现在有A,在A中启动B,此时在A中Intent中加上这个标记。此时B就是以FLAG_ACTIVITY_BROUGHT_TO_FRONT方式启动,此时在B中再启动C,D(正常启动C,D),如果这个时候在D中再启动B,这个时候最后的栈的情况是 A,C,D,B。如果在A,B,C,D正常启动的话,不管B有没有用FLAG_ACTIVITY_BROUGHT_TO_FRONT启动,此时在D中启动B的话,还是会变成A,C,D,B的。

FLAG_ACTIVITY_NO_USER_ACTION
onUserLeaveHint()作为activity周期的一部分,它在activity因为用户要跳转到别的activity而要退到background时使用。比如,在用户按下Home键,它将被调用。比如有电话进来(不属于用户的选择),它就不会被调用。
那么系统如何区分让当前activity退到background时使用是用户的选择?
它是根据促使当前activity退到background的那个新启动的Activity的Intent里是否有FLAG_ACTIVITY_NO_USER_ACTION来确定的。
注意:调用finish()使该activity销毁时不会调用该函数

FLAG_ACTIVITY_NO_HISTORY
意思就是说用这个FLAG启动的Activity,一旦退出,它不会存在于栈中,比如原来是A,B,C这个时候再C中以这个FLAG启动D的,D再启动E,这个时候栈中情况为A,B,C,E。

Activity相关属性taskAffinity
Activity 中的 android:taskAffinity 这个属性介绍:
Activity为Task拥有的一个affinity。拥有相同的affinity的Activity理论上属于相同的Task(在用户的角度是相同的“应用程序”)。Task的affinity是由它的根Activity决定的。 
affinity决定两件事情——Activity重新宿主的Task(参考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK标志启动的Activity宿主的Task。
默认情况,一个应用程序中的所有Activity都拥有相同的affinity。捏可以设定这个特性来重组它们,甚至可以把不同应用程序中定义的Activity放置到相同的Task中。为了明确Activity不宿主特定的Task,设定该特性为空的字符串。
如果这个特性没有设置,Activity将从应用程序的设定那里继承下来(参考<application>元素的taskAffinity特性)。应用程序默认的affinity的名字是<manifest>元素中设定的package名。


本文转载自:http://blog.csdn.net/robertcpp/article/details/51455321

共有 人打赏支持
robertchao
粉丝 3
博文 55
码字总数 30285
作品 0
海淀
Android工程师
Android中Activity启动模式详解

Android中Activity启动模式详解   在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方...

大凉龙雀
2013/05/25
0
1
针对Activity的启动模式理解1---standard模式

Activity有4种启动模式: standard、singleTop、singleTask、singleInstance; Activity的四种启动模式 涉及到了Task任务: 在Android中一些列相关的操作所启动的Activity构成了一个完整的任...

风清入舞
2012/08/28
0
0
Android中Activity启动模式详解

 在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。   Android总Activity的启动...

带梦想一7飞
2013/05/23
0
0
Activity的四种加载方式

配置activity时可指定android:launchMode属性,该属性用于配置改Activity的启动模式。该属性支持以下4个属性值。 standard:标准模式,默认的加载模式 singleTop:Task栈顶单例模式 singleTa...

dailei1021
2015/11/21
0
0
Android Activity中的四种启动模式

Android总Activity的启动模式分为四种: <activity android:name=".MainActivity" android:launchMode="standard" /> 【standard】 默认模式启动模式,每次激活Activity时都会创建Activity,......

恰同学少年
2015/07/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

聊聊clean code

clean code,顾名思义就是整洁的代码,或者说清晰、漂亮的代码,相信大多数工程师都希望自己能写出这样的代码。 也许这是个千人千面的话题,每个工程师都有自己的理解。比如我,从一个天天被...

Skqing
29分钟前
3
0
redis连接报错—— (error) NOAUTH Authentication required.

1.redis报认证错误 redis客户端连接成功,但是操作报异常——(error) NOAUTH Authentication required 错误的含义是说你没有认证,说明没有使用密码连接 redis-cli -h 127.0.0.1 -p 6379 -a ...

啊哈关关
35分钟前
2
0
地理位置坐标标准以及转换

/** * 地理位置坐标标准以及转换 * * 1.WGS-84原始坐标系,一般用国际GPS纪录仪记录下来的经纬度,通过GPS定位拿到的原始经纬度,Google和高德地图定位的的经纬度(国外)都是基于W...

葉者
37分钟前
2
0
Generator-ES6

基本概念 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。 Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装...

简心
55分钟前
6
0
FullCalendar日历插件说明文档

普通显示设置 属性 描述 默认值 header 设置日历头部信息。 如果设置为false,则不显示头部信息。包括left,center,right左中右三个位置,每个位置都可以对应以下不同的配置: title: 显示当...

ada_young
56分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部