Activity Intent相关FLAG介绍

来源:互联网 发布:linux sprintf函数 编辑:程序博客网 时间:2024/05/17 07:06
先首先简单介绍下Task和Activity的关系

Task就像一个容器,而Activity就相当与填充这个容器的东西,第一个东西(Activity)则会处于最下面,最后添加的东西(Activity)则会在最上面。从Task中取出东西(Activity)是从最顶端取出,也就是说最先取出的是最后添加的东西(Activity),以此类推,最后取出的是第一次添加的Activity,而Activity在Task中的顺序是可以控制的,在Activity跳转时用到Intent Flag可以设置新建activity的创建方式;
  
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了

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有四种加载模式:standard(默认), singleTop, singleTask和 singleInstance。以下逐一举例说明他们的区别:

standard:Activity的默认加载方法,即使某个Activity在 Task栈中已经存在,另一个activity通过Intent跳转到该activity,同样会新创建一个实例压入栈中。例如:现在栈的情况为:A B C D,在D这个Activity中通过Intent跳转到D,那么现在的栈情况为: A B C D D 。此时如果栈顶的D通过Intent跳转到B,则栈情况为:A B C D D B。此时如果依次按返回键,D  D C B A将会依次弹出栈而显示在界面上。

singleTop:如果某个Activity的Launch mode设置成singleTop,那么当该Activity位于栈顶的时候,再通过Intent跳转到本身这个Activity,则将不会创建一个新的实例压入栈中。例如:现在栈的情况为:A B C D。D的Launch mode设置成了singleTop,那么在D中启动Intent跳转到D,那么将不会新创建一个D的实例压入栈中,此时栈的情况依然为:A B C D。但是如果此时B的模式也是singleTop,D跳转到B,那么则会新建一个B的实例压入栈中,因为此时B不是位于栈顶,此时栈的情况就变成了:A B C D B。

singleTask:如果某个Activity是singleTask模式,那么Task栈中将会只有一个该Activity的实例。例如:现在栈的情况为:A B C D。B的Launch mode为singleTask,此时D通过Intent跳转到B,则栈的情况变成了:A B。而C和D被弹出销毁了,也就是说位于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。
好了,现在有一个问题就是这时这种情况下如果用户点击了Home键,则再也回不到D的即时界面了。如果想解决这个问题,可以为D在Manifest.xml文件中的声明加上
                                                 
                                                 
                                              

加上这段之后,也就是说该程序中有两个这种声明,另一个就是那个正常的根 activity,在打成apk包安装之后,在程序列表中能看到两个图标,但是如果都运行的话,在任务管理器中其实也只有一个。上面的情况点击D的那个图标就能回到它的即时界面(比如一个EditText,以前输入的内容,现在回到之后依然存在)。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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:例如现在栈情况为:A B C。C通过intent跳转到D,这个intent添加FLAG_ACTIVITY_NO_HISTORY标志,则此时界面显示D的内容,但是它并不会压入栈中。如果按返回键,返回到C,栈的情况还是:A B C。如果此时D中又跳转到E,栈的情况变为:A B C E,此时按返回键会回到C,因为D根本就没有被压入栈中。

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

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Activity的主要属性:

allowTaskReparenting:设置成true时,和Intent的FLAG_ACTIVITY_NEW_TASK 标记类似。

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

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

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

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手切了山药很痒怎么办 山药弄的身上痒怎么办 疣迪去除疣体怎么办 尖锐湿庞出血了怎么办 尿道口周围烂了怎么办 尖锐湿庞复发了怎么办 宝宝脸上长湿疹怎么办如何治疗 孕妇得尖锐湿庞怎么办 痘痘留下的小坑怎么办 花洒固定座坏了怎么办 脚上起水泡烂了怎么办 月经期吃了芒果怎么办 月经量少又黑怎么办 来月经黑色的血怎么办 月经来的是黑色怎么办 来月经有血块是怎么办 月经又少又黑怎么办 来月经发黑又少怎么办 月经血发黑量少怎么办 做人流后肚子胀怎么办 怀孕见红了肚子不痛怎么办 月经来是黑色的怎么办 怀孕了长了痔疮怎么办 怀孕了有外痔疮怎么办 孕妇长痔疮很痛怎么办 孕9个月尿路感染怎么办 旁边有人尿不出来怎么办 外阴破皮了应该怎么办 脸上长脂肪粒怎么办怎么能消除 挤黑头留下的坑怎么办 长痘留下的坑怎么办 鼻子上留下黑印怎么办 狗狗眼里长息肉怎么办 狗狗眼角长息肉怎么办 脸上长了好多脂肪粒怎么办 脸上毛孔粗大有黑头怎么办 脸颊毛孔粗有黑头怎么办 鼻子上有黑头怎么办小窍门 脸上很多粉刺和油脂粒怎么办 毛孔里都是角栓怎么办 脸上长了很多脂肪粒怎么办