Android Task Flag

本文深入探讨了Android中Activity的生命周期管理和Task的概念,包括标准、单顶、单任务、单实例、新建任务、单任务等启动模式,以及Intent的setFlag和addFlag的区别。同时介绍了Task的前台与后台状态,以及如何使用Intent对象中的Flag标志来控制Activity的启动行为。文章还详细解释了Activity的清理模式和生命周期方法,以及如何在系统清理BackStack时保存和恢复数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


回退栈(Back Stack):每个Task都存在一个BackStack,而系统中可以存在多个Task,但是每次只有一个Task获得前台焦点,一般而言,系统允许用户在多个Task中切换,而被至于后台的Task中的Activity,将被置于Stopped状态。

Task 就像是一个 stack,一个一个的 activity 是构成 stack 的元素,做着入栈 (push) 和出栈 (pop-up)这样简单重复性的劳动.

Android的每个Activity都运行在堆栈中,一个Task栈可以有多个Activity,同一个Activity也可以在不同的Task栈中。

Task是分前台和后台的。一般当用户启动一个新的Task或者按Home键回到桌面时,当前Task就会被转入后台。如果用户长时间离开某个Task,这个Task只保留root Activity,其他的都会被销毁。

Activity的LaunchMode属性可以指定Activity和Task之间的关系。

?
1
2
3
4
android:launchMode= "standard"
android:launchMode= "singleTop"
android:launchMode= "singleTask"
android:launchMode= "singleInstance"

系统默认是standard的,即同一个Activity可以被实例化多次。


1. Intent的setFlag和addFlag有什么区别?

setFlag是把之前的替换掉,addFlag是添加新的

 有关的 Intent对象中设置的Flag标志:


默认情况下,通过 startActivity() 启动一个新的 Activity,新的 Activity 将会和调用者在同一个 stack 中。如果Intent 对象里包含了 FLAG_ACTION_NEW_TASK,情况将发生变化,系统将为新的 Activity “寻找”一个不同于调用者的 Task。不过要找的 Task 是不是一定就是 NEW 呢?如果是第一次执行,则这个设想成立;如果说不是第一次执行,也就是说已经有一个包含此 Activity 的Task 存在,则不会再启动 Activity。



1 FLAG_ACTIVITY_BROUGHT_TO_FRONT 
    这个标志一般不是由程序代码设置的,如在launchMode中设置singleTask模式时系统帮你设定。

    //如果activity在task存在,拿到最顶端,不会启动新的Activity

2 FLAG_ACTIVITY_CLEAR_TOP
    如果设置,并且这个Activity已经在当前的Task中运行,因此,不再是重新启动一个这个Activity的实例,而是在这个Activity上方的所有Activity都将关闭,然后这个Intent会作为一个新的Intent投递到老的Activity(现在位于顶端)中。 
    举个例子~假设一个Task中包含这些Activity:A,B,C,D。如果D调用了startActivity(),并且包含一个指向Activity B的Intent,那么,C和D都将结束,然后B接收到这个Intent,因此,目前stack的状况是:A,B。 
    上例中正在运行的Activity B既可以在onNewIntent()中接收到这个新的Intent,也可以把自己关闭然后重新启动来接收这个Intent。如果它的启动模式声明为“multiple”(默认值),并且你没有在这个Intent中设置FLAG_ACTIVITY_SINGLE_TOP标志,那么它将关闭然后重新创建;对于其它的启动模式,或者在这个Intent中设置FLAG_ACTIVITY_SINGLE_TOP标志,都将把这个Intent投递到当前这个实例的onNewIntent()中。 
    这个启动模式还可以与FLAG_ACTIVITY_NEW_TASK结合起来使用:用于启动一个Task中的根Activity,它会把那个Task中任何运行的实例带入前台,然后清除它直到根Activity。这非常有用,例如,当从Notification Manager处启动一个Activity。


3 FLAG_ACTIVITY_SINGLE_TOP,和singleTop对应

  如果设置,当这个Activity位于历史stack的顶端运行时,不再启动一个新的.

singleTop是指如果Task栈现在的顺序是A,B,C,D。那么如果现在传来一个intent是启动D的,那么D是会调用onNewIntent来接受传来的intent,而不会重新启动D。所以Task栈的顺序还是A,B,C,D。而不是A,B,C,D,D.

 singleTop的应用场景很多,一般适用于可以复用而又有多个开启渠道的Activity,避免当一个Activity已经开启并获得焦点后,再次重复开启。比如说Android系统浏览器的书签页面,就是一个singleTop模式的Activity。Android的浏览器是基于WebKit内核编写的,它是支持JavaScript脚本语言的,可以通过JavaScript脚本设置浏览器书签,这样如果存在多个页面存在保存书签的JavaScript脚本,就会导致书签页面被多次开启,所以书签页面被设置为singleTop模式,这样可以避免在保存多个书签的时候重复开启书签页面。

4 FLAG_ACTIVITY_NEW_TASK,和singleTask对应

如果设置该标志,这个Activity会成为历史stack中一个新Task的开始。如果存在一个不同于当前调用者的Task(Task B),且该Task有目标Activity的存在,则切换到Task B中的Activity,执行Activity的onNewIntent方法。 


singleTask的的适用场景为一般程序的主页面,当回退到主页面的时候,清除BackStack中,它之上的所有Activity,这样避免程序导航逻辑的混乱。比如Android系统的浏览器的主页面,就是singleTask模式的,上面提到,android下浏览器是Webkit内核的,它是由C语言编写的,而每次打开新的网页如果重新开启一个Activity,是非常耗费系统资源的(需要解析HTML、Script脚本),所以被设置为singleTask模式,这样在浏览器应用里,无论打开多少个页面,使用的都是同一个Activity。所以以后如果存在很耗费系统资源的Activity,可以考虑使用singleTask开启模式。


5 FLAG_ACTIVITY_MUTIPLE_TASK

    当设置该标志时,新的Task总是会启动来处理Intent,而不管这是是否已经有一个Task可以处理相同的事情。 
    由于默认的系统不包含图形Task管理功能,因此,你不应该使用这个标志,除非你提供给用户一种方式可以返回到已经启动的Task。 
    如果FLAG_ACTIVITY_NEW_TASK标志没有设置,这个标志被忽略。


6 single instance

singleInstance是指Activity只能实例化一次并且独占一个Task。

被标记为singleInstance启动模式的Activity,在启动的时候,会开启一个新的BackStack,这个BackStack里只有一个Activity的实例存在,并且把这个BackStack获得焦点。这是一种很极端的模式,它会导致整个设备的操作系统里,只会存在一个这个Activity示例,无论是从何处被启动的。

   singleInstance一般适用于需要在系统中只存在一个实例的场景,比如Android系统的来电页面,多次来电均使用的是一个Activity。






这些标志有些是可以组合使用的,比如说clear top和single top同时用,则将目标Activity在Task栈上面的Activity都销毁,并且将该intent传递给栈顶的Activity,此Activity可以回调onNewIntent方法.



part 2 : 系统开启一个Task、BackStack、以及backstack清理,参考

1. start Activity

我们在开发一个应用程序的时候,需要指定应用程序的入口Activity,通过在AndroidManifest.xml清单文件中某个<Activity/>标签内,使用<intent-filter/>标签内指定。需要设置action为"android.intent.action.MAIN",设置category为"android.intent.category.LAUNCHER"。

这样,当用户点击应用程序图标之后,就会以这个入口Activity为基础,创建一个任务(Task),而这个Activity为这个Task中的第一个Activity,称为根Activity。


2. task

Android中存在多个Task,但是同一时刻只有一个Task被置于前台,其它的均为后台,而后台的Task内的Activity,均为Stopped状态。Android系统中有多种方式切换Task,比如:按HOME键回到桌面、长按HOME键切换到其他Task等。而在同一个Task中,也只有BackStack最上面的Activity处于获得焦点的状态,其它也为Stopped,每当系统需要把Activity置于Stopped时,都会自动在Bundle中保其内控件的状态数据(需要为控件设置ID标识),比如:控件输入值、滚动条位置,以便下次获得焦点的时候自动还原。


当系统资源不足的时候,如内存不足,会自动回收一些优先级比较低的组件的线程,以释放资源给新的组件使用。那么就存在问题了,当一个Task被切换到后台之后,如果系统资源告急,自动销毁了某个后台Task中的Activity(除了根Activity外),当用户再次切换回那个Task的时候,BackStack中存在这个Activity的标记,但是内存中已经不存在这个Activity的实例了,这个时候,系统就会通过Bundle来重新创建一个Activity用于还原它,这样保证了用户体验,使用户还是感觉在之前的页面中操作。但是这种情况下,Bundle是不会保存之前Activity中的信息的,比如:控件输入值、滚动条位置。这个时候,如果这个Activity的内容很重要的话,需要我们以编码的方式去保存数据,并在重新创建的时候,以编码的方式还原这个数据。

  以上两种情况都需要用到两个Activity的生命周期方法,onSaveInstanceState()和onRestoreInstanceState()。但是第一种情况是系统帮我们维护的,第二种特殊情况,需要开发人员编码维护。下面是这两个方法的签名:

  • protected void onSaveInstanceState(Bundle outState):当Activity被系统回收的时候被调用 ,用这个方法保存Activity中需要保存的数据,存入outState参数即可。
  • protected void onRestoreInstanceState(Bundle savedInstanceState):当Activity被系统恢复的时候被调用,从Bundle中取出数据,设置会控件中,当然也可以通过重写onCreate()方法来设置数据,因为onCreate()一样可以获取到,但是推荐使用onRestoreInstanceState()。

3 back stack清理


在Android系统的清单文件中,不光为我们提供了设置启动模式的属性android:LauncherMode,还为我们提供了Activity的清理模式,有如下几个:

  • android:alwaysRetainTaskState:这个属性只对根Activity有效,默认为false,当其设置为true的时候,当这个根Activity失去焦点被置于后台的时候,如不出现意外情况,其中的Activity将不会被系统回收。
  • android:clearTaskOnTask:这个属性只对根Activity有效,当这个根Activity失去焦点被置于后台的时候,会清理BackStack中根Activity之上的所有Activity,并在下次获得焦点的时候显示根Activity。
  • android:finishOnTaskLaunch:这个属性只应用于单个Activity,它默认为false,当其设置为true的时候,当前Task如果在这个Activity获得焦点的时候被切换到后台,那么这个Activity直接被销毁,哪怕只是离开一小会儿。






### 回答1: Androidintent multi_task flag的具体含义是指当打开一个新的Activity时,如果设置了multi_task flag,则会在后台创建新的task,而不是在当前task中打开新的Activity。 ### 回答2: Android中,Intent的multi_task标志是指一个意图可以同时启动多个任务。当我们在启动一个Activity时,可以设置Intentflags属性为FLAG_ACTIVITY_MULTIPLE_TASK。这个标志告诉系统,当前的Activity可以在其自己的任务栈中启动。 具体来说,当我们使用multi_task标志时,通过startActivity()方法启动Activity时,系统会根据设置的flag来决定Activity的启动行为。如果该Activity已经存在于一个任务栈中,那么系统会创建一个新的任务栈,并在新的任务栈中启动这个Activity。这样可以同时打开多个相同的Activity,并且它们各自运行在不同的任务栈中。 使用multi_task标志可以实现一些特定的功能需求,比如多窗口分屏、在同一个应用中同时打开多个相同的Activity等。通过在Intent中设置这个标志,我们可以灵活地控制Activity的启动模式,增加用户的使用体验。 需要注意的是,使用multi_task标志时,要特别小心各个Activity之间的共享数据和资源的问题,需要进行适当的处理,以免出现意外情况。同时,使用该标志时,也要考虑到设备的性能和用户的使用习惯,避免过多占用系统资源。 总之,Intent的multi_task标志是指可以同时启动多个任务的意图。在Android开发中,我们可以通过设置这个标志来控制Activity的启动行为,从而满足不同功能需求。 ### 回答3: 在Android中,Intent是一种在组件之间传递信息的机制。Intent有很多的标志位(flag)可用于指定Intent的行为。其中,multi_task flag是一个用于指定启动Activity时的行为的标志位。 multi_task flag代表启动一个新的任务(Task)。在Android中,一个任务是一系列相关联的活动(Activity)的集合。当我们使用Intent启动一个Activity时,系统会创建一个新的任务,并将该Activity添加到该任务中。 具体来说,使用multi_task flag启动一个Activity时,系统会为该Activity创建一个独立的任务,并将该Activity置于任务栈的顶部。该Activity会显示在最近使用过的应用列表中,并且可以通过系统的任务切换(Task Switcher)功能进行切换。 multi_task flag的具体含义是允许Activity在独立的任务中运行。对于需要在不同任务之间切换的场景,例如在多窗口模式下同时运行多个应用程序,或者在某些设备的分屏模式下使用多个应用程序时,使用multi_task flag可以很方便地创建并切换任务。 需要注意的是,使用multi_task flag启动Activity时,可能会受到一些限制。例如,一些权限和启动模式可能会影响Activity是否能够在新的任务中启动。因此,在使用multi_task flag启动Activity时,需要仔细考虑相关的权限和启动模式设置。 总之,Android中multi_task flag具体含义是允许Activity在独立的任务中运行,以实现在不同任务之间切换的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值