Android 关于Acitivity 的setFlag以及launchmode的总结

Posted zhujiabin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 关于Acitivity 的setFlag以及launchmode的总结相关的知识,希望对你有一定的参考价值。

Intent几种常见的flags:
1.FLAG_ACTIVITY_NEW_TASK:当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的 taskAffinity属性进行匹配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中,如果查找 无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标 Activity放置于此task。注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的 Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主。
2.FLAG_ACTIVITY_CLEAR_TOP: 当Intent对象包含这个标记时,如果在栈中发现存在Activity实例,则清空这个实例之上的Activity,使其处于栈顶。 
3. FLAG_ACTIVITY_SINGLE_TOP: 当task中存在目标Activity实例并且位于栈的顶端时,不再创建一个新的,直接利用这个实例
  FLAG_ACTIVITY_CLEAR_TOP |FLAG_ACTIVITY_SINGLE_TOP:example:A-B-C-B,如果B在栈中则不创建一个新B,如果不存在则创建。 
4.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:如果一个Intent中包含此属性,则它转向的那个Activity以及在那个Activity其上的所有Activity都会在task重置时被清除出 task。当我们将一个后台的task重新回到前台时,系统会在特定情况下为这个动作附带一个 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,意味着必要时重置task,这时 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET就会生效。经过测试发现,对于一个处于后台的应用,如果在主选单点击应用,这个 动作中含有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,长按Home键,然后点击最近记录,这个动作不含 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,所以前者会清除,后者不会。
5.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED:
这个标记在以下情况下会生效:1.启动Activity时创建新的task来放置Activity实例;2.已存在的task被放置于前台。系统会根据 affinity对指定的task进行重置操作,task会压入某些Activity实例或移除某些Activity实例。我们结合上面的 CLEAR_WHEN_TASK_RESET可以加深理解。
<activity>的task相关属性:
1.android:allowTaskReparenting
这个属性用来标记一个Activity实例在当前应用退居后台后,是否能从启动它的那个task移动到有共同affinity的task,“true”表示可以移动,“false”表示它必须呆在当前应用的task中,默认值为false。如果一个这个Activity的<activity>元素没有设定此属性,设定在< application>上的此属性会对此Activity起作用。例如在一个应用中要查看一个web页面,在启动系统浏览器Activity后,这个Activity实例和当前应用处于同一个task,当我们的应用退居后台之后用户再次从主选单中启动应用,此时这个Activity实例将会重新宿主到Browser应用的task内,在我们的应用中将不会再看到这个Activity实例,而如果此时启动Browser应用,就会发现,第一个界面就是我们刚才打开的web页面,证明了这个Activity实例确实是宿主到了Browser应用的task内。
2.android:alwaysRetainTaskState
这个属性用来标记应用的task是否保持原来的状态,“true”表示总是保持,“false”表示不能够保证,默认为“false”。此属性只对task的根Activity起作用,其他的Activity都会被忽略。
默认情况下,如果一个应用在后台呆的太久例如30分钟,用户从主选单再次选择该应用时,系统就会对该应用的task进行清理,除了根 Activity,其他Activity都会被清除出栈,但是如果在根Activity中设置了此属性之后,用户再次启动应用时,仍然可以看到上一次操作 的界面。
这个属性对于一些应用非常有用,例如Browser应用程序,有很多状态,比如打开很多的tab,用户不想丢失这些状态,使用这个属性就极为恰当。
3.android:clearTaskOnLaunch
这个属性用来标记是否从task清除除根Activity之外的所有的Activity,“true”表示清除,“false”表示不清除,默认为“false”。同样,这个属性也只对根Activity起作用,其他的Activity都会被忽略。
如果设置了这个属性为“true”,每次用户重新启动这个应用时,都只会看到根Activity,task中的其他Activity都会被清除出 栈。如果我们的应用中引用到了其他应用的Activity,这些Activity设置了allowTaskReparenting属性为“true”,则它们会被重新宿主到有共同affinity的task中。
<Activity>的四种启动模式:
  在android里,有4种activity的启动模式,分别为:
    “standard” (默认)
    “singleTop”
    “singleTask”
    “singleInstance”
1. 如何决定所属task
“standard”和”singleTop”的activity的目标task,和收到的Intent的发送者在同一个task内,除非intent包括参数FLAG_ACTIVITY_NEW_TASK。
如果提供了FLAG_ACTIVITY_NEW_TASK参数,会启动到别的task里。
2. 是否允许多个实例
“standard”和”singleTop”可以被实例化多次,并且存在于不同的task中,且一个task可以包括一个activity的多个实例;
“singleTask”和”singleInstance”则限制只生成一个实例,并且是task的根元素。
singleTop要求如果创建intent的时候栈顶已经有要创建 的Activity的实例,则将intent发送给该实例,而不发送给新的实例。
3. 是否允许其它activity存在于本task内
“singleInstance”独占一个task,其它activity不能存在那个task里;如果它启动了一个新的activity,不管新的 activity的launch mode 如何,新的activity都将会到别的task里运行(如同加了FLAG_ACTIVITY_NEW_TASK参数)。
而另外三种模式,则可以和其它activity共存。
4. 是否每次都生成新实例
“standard”对于没一个启动Intent都会生成一个activity的新实例;
“singleTop”的activity如果在task的栈顶的话,则不生成新的该activity的实例,直接使用栈顶的实例,否则,生成该activity的实例。
比如现在task栈元素为A-B-C-D(D在栈顶),这时候给D发一个启动intent,如果D是 “standard”的,则生成D的一个新实例,栈变为A-B-C-D-D。
如果D是singleTop的话,则不会生产D的新实例,栈状态仍为A-B-C-D
如果这时候给B发Intent的话,不管B的launchmode是”standard” 还是 “singleTop” ,都会生成B的新实例,栈状态变为A-B-C-D-B。
“singleInstance”是其所在栈的唯一activity,它会每次都被重用。
“singleTask”如果在栈顶,则接受intent,否则,该intent会被丢弃,但是该task仍会回到前台。
当已经存在的activity实例处理新的intent时候,会调用onNewIntent()方法
如果收到intent生成一个activity实例,那么用户可以通过back键回到上一个状态;如果是已经存在的一个activity来处理这个intent的话,用户不能通过按back键返回到这之前的状态。
总结如下:
standard  每次都会新建,每个Task都可以有,且每个Task都可以有多个实例(每个Task都可以有,且可以有多个)
singleTop 当前实例如果在栈顶,就不新建实例,调用其OnNewIntent。 如不在栈顶,则新建实例 (每个Task都可以有,且可以有多个,在栈顶时可复用)
singleTask 新建一个Task,如果已经有其他的Task并且包含该实例,那就直接调用那个Task的实例。(只有一个Task中会有)
singleInstance 新建一个Task,且在该Task中只有它的唯一一个实例。 (只有一个Task会有,且该Task中只有它)
FLAG_ACTIVITY_NEW_TASK  类似singleTask
FLAG_ACTIVITY_SINGLE_TOP 类似singleTop 
FLAG_ACTIVITY_CLEAR_TOP 无对应

 

 

  1. Intent几种常见的flags:
  2.  
    1.FLAG_ACTIVITY_NEW_TASK:当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的 taskAffinity属性进行匹配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中,如果查找 无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标 Activity放置于此task。注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的 Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主。
  3.  
    2.FLAG_ACTIVITY_CLEAR_TOP: 当Intent对象包含这个标记时,如果在栈中发现存在Activity实例,则清空这个实例之上的Activity,使其处于栈顶。
  4.  
    3. FLAG_ACTIVITY_SINGLE_TOP: 当task中存在目标Activity实例并且位于栈的顶端时,不再创建一个新的,直接利用这个实例
  5.  
    FLAG_ACTIVITY_CLEAR_TOP |FLAG_ACTIVITY_SINGLE_TOP:example:A-B-C-B,如果B在栈中则不创建一个新B,如果不存在则创建。
  6.  
    4.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:如果一个Intent中包含此属性,则它转向的那个Activity以及在那个Activity其上的所有Activity都会在task重置时被清除出 task。当我们将一个后台的task重新回到前台时,系统会在特定情况下为这个动作附带一个 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,意味着必要时重置task,这时 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET就会生效。经过测试发现,对于一个处于后台的应用,如果在主选单点击应用,这个 动作中含有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,长按Home键,然后点击最近记录,这个动作不含 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,所以前者会清除,后者不会。
  7.  
    5.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED:
  8.  
    这个标记在以下情况下会生效:1.启动Activity时创建新的task来放置Activity实例;2.已存在的task被放置于前台。系统会根据 affinity对指定的task进行重置操作,task会压入某些Activity实例或移除某些Activity实例。我们结合上面的 CLEAR_WHEN_TASK_RESET可以加深理解。
  9.  
    <activity>的task相关属性:
  10.  
    1.android:allowTaskReparenting
  11.  
    这个属性用来标记一个Activity实例在当前应用退居后台后,是否能从启动它的那个task移动到有共同affinity的task,“true”表示可以移动,“false”表示它必须呆在当前应用的task中,默认值为false。如果一个这个Activity的<activity>元素没有设定此属性,设定在< application>上的此属性会对此Activity起作用。例如在一个应用中要查看一个web页面,在启动系统浏览器Activity后,这个Activity实例和当前应用处于同一个task,当我们的应用退居后台之后用户再次从主选单中启动应用,此时这个Activity实例将会重新宿主到Browser应用的task内,在我们的应用中将不会再看到这个Activity实例,而如果此时启动Browser应用,就会发现,第一个界面就是我们刚才打开的web页面,证明了这个Activity实例确实是宿主到了Browser应用的task内。
  12.  
    2.android:alwaysRetainTaskState
  13.  
    这个属性用来标记应用的task是否保持原来的状态,“true”表示总是保持,“false”表示不能够保证,默认为“false”。此属性只对task的根Activity起作用,其他的Activity都会被忽略。
  14.  
    默认情况下,如果一个应用在后台呆的太久例如30分钟,用户从主选单再次选择该应用时,系统就会对该应用的task进行清理,除了根 Activity,其他Activity都会被清除出栈,但是如果在根Activity中设置了此属性之后,用户再次启动应用时,仍然可以看到上一次操作 的界面。
  15.  
    这个属性对于一些应用非常有用,例如Browser应用程序,有很多状态,比如打开很多的tab,用户不想丢失这些状态,使用这个属性就极为恰当。
  16.  
    3.android:clearTaskOnLaunch
  17.  
    这个属性用来标记是否从task清除除根Activity之外的所有的Activity,“true”表示清除,“false”表示不清除,默认为“false”。同样,这个属性也只对根Activity起作用,其他的Activity都会被忽略。
  18.  
    如果设置了这个属性为“true”,每次用户重新启动这个应用时,都只会看到根Activity,task中的其他Activity都会被清除出 栈。如果我们的应用中引用到了其他应用的Activity,这些Activity设置了allowTaskReparenting属性为“true”,则它们会被重新宿主到有共同affinity的task中。
  19.  
    <Activity>的四种启动模式:
  20.  
    在android里,有4种activity的启动模式,分别为:
  21.  
    “standard” (默认)
  22.  
    “singleTop”
  23.  
    “singleTask”
  24.  
    “singleInstance”
  25.  
    1. 如何决定所属task
  26.  
    “standard”和”singleTop”的activity的目标task,和收到的Intent的发送者在同一个task内,除非intent包括参数FLAG_ACTIVITY_NEW_TASK。
  27.  
    如果提供了FLAG_ACTIVITY_NEW_TASK参数,会启动到别的task里。
  28.  
    2. 是否允许多个实例
  29.  
    “standard”和”singleTop”可以被实例化多次,并且存在于不同的task中,且一个task可以包括一个activity的多个实例;
  30.  
    “singleTask”和”singleInstance”则限制只生成一个实例,并且是task的根元素。
  31.  
    singleTop要求如果创建intent的时候栈顶已经有要创建 的Activity的实例,则将intent发送给该实例,而不发送给新的实例。
  32.  
    3. 是否允许其它activity存在于本task内
  33.  
    “singleInstance”独占一个task,其它activity不能存在那个task里;如果它启动了一个新的activity,不管新的 activity的launch mode 如何,新的activity都将会到别的task里运行(如同加了FLAG_ACTIVITY_NEW_TASK参数)。
  34.  
    而另外三种模式,则可以和其它activity共存。
  35.  
    4. 是否每次都生成新实例
  36.  
    “standard”对于没一个启动Intent都会生成一个activity的新实例;
  37.  
    “singleTop”的activity如果在task的栈顶的话,则不生成新的该activity的实例,直接使用栈顶的实例,否则,生成该activity的实例。
  38.  
    比如现在task栈元素为A-B-C-D(D在栈顶),这时候给D发一个启动intent,如果D是 “standard”的,则生成D的一个新实例,栈变为A-B-C-D-D。
  39.  
    如果D是singleTop的话,则不会生产D的新实例,栈状态仍为A-B-C-D
  40.  
    如果这时候给B发Intent的话,不管B的launchmode是”standard” 还是 “singleTop” ,都会生成B的新实例,栈状态变为A-B-C-D-B。
  41.  
    “singleInstance”是其所在栈的唯一activity,它会每次都被重用。
  42.  
    “singleTask”如果在栈顶,则接受intent,否则,该intent会被丢弃,但是该task仍会回到前台。
  43.  
    当已经存在的activity实例处理新的intent时候,会调用onNewIntent()方法
  44.  
    如果收到intent生成一个activity实例,那么用户可以通过back键回到上一个状态;如果是已经存在的一个activity来处理这个intent的话,用户不能通过按back键返回到这之前的状态。
  45.  
    总结如下:
  46.  
    standard 每次都会新建,每个Task都可以有,且每个Task都可以有多个实例(每个Task都可以有,且可以有多个)
  47.  
    singleTop 当前实例如果在栈顶,就不新建实例,调用其OnNewIntent。 如不在栈顶,则新建实例 (每个Task都可以有,且可以有多个,在栈顶时可复用)
  48.  
    singleTask 新建一个Task,如果已经有其他的Task并且包含该实例,那就直接调用那个Task的实例。(只有一个Task中会有)
  49.  
    singleInstance 新建一个Task,且在该Task中只有它的唯一一个实例。 (只有一个Task会有,且该Task中只有它)
  50.  
    FLAG_ACTIVITY_NEW_TASK 类似singleTask
  51.  
    FLAG_ACTIVITY_SINGLE_TOP 类似singleTop
  52.  
    FLAG_ACTIVITY_CLEAR_TOP 无对应
  53.  

以上是关于Android 关于Acitivity 的setFlag以及launchmode的总结的主要内容,如果未能解决你的问题,请参考以下文章

Android_Acitivity

Android 是怎么启动一个Acitivity的

android开发问题:如何在当前Acitivity中用代码获取上一个Activity名称?

❥关于C++之std::ios_base::fmtflags/setf

acitivity启动原理

Acitivity之Intent调用方法