`

Android 学习 之 Activity 堆栈信息

阅读更多

在android中,一个activity组件可以激活另一个activity组件(可能属于另一个应用程序)。

若新的被激活的activity组件属于另一个应用程序,则那个activity组件会运行在那个应用程序的进程中,但是从用户的角度来看,好像就是属于本应用程序一样。Android是通过将之前的activity组件和新被激活的activity组件放入同一个任务栈来实现这个功能的。从用户的角度看,一个任务栈就代表了“一个应用程序”。它实际上是一个栈,里面放着一组被排列好的相关的activity组件。位于栈底的activity(根activity)就是开启这个任务栈的activity组件,一般情况下,就是应用程序的主界面。而位于栈顶的activity组件即代表当前被激活的activity组件(可接收用户行为的activity)。

任务栈中包含了activity组件的对象,且任务栈中可以包含有某一个activity组件类型的多个实例对象。在任务栈中的activity组件不能被重排序,只能被压栈和弹栈。

任务栈不是某个类型,也不是某一个元素,它是一组activity组件的组织形式。所以没有办法在不影响任务栈中的activity组件的情况下,单独设置任务栈的参数。根activity的参数既是整个任务栈的参数,它会影响任务栈中的所有activity组件。

当某个应用程序在前后台切换的时候,实际上就是代表这个应用程序的一个任务栈在前后台切换。

刚刚描述的行为是activity和任务栈的默认行为,但也有办法在很多方面对它进行修改:

方法1:在发送的请求(即Intent对象)中设置一些标记。

方法2:在manifest文件中,对接收请求(即Intent对象)的activity组件设置一些属性。

所以在请求者和接收者中都可以进行控制。

在Intent对象中主要的标志有:

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

FLAG_ACTIVITY_SINGLE_TOP

在<activity>标签中,主要的属性有:

taskAffinity android:taskAffinity="com.cardroid.sdhc" 表示两个应用里面的亲属关系,如果一个应用的某个ACTIVITY和另一个应用的ACTIVITY设置这个属性
然后,这两个ACTIVITY显示后点击HOME键盘,从一个应用启动就会显示点击HOME的那个ACTIVITY

launchMode

allowTaskReparenting

clearTaskOnLaunch

alwaysRetainTaskState

finishOnTaskLaunch

接下来的内容就会讲解一些Intent标志和<activity>标签属性的作用和用法。

1.亲属关系和新的任务

默认情况下,一个应用程序中的activity组件彼此之间是亲属关系――也就是说它们属于同一个任务栈。但是我们可以通过设置某个<activity>标签的taskAffinity属性来为这个activity组件设置亲属关系。在不同的应用程序中定义的activity组件可以共用同一个亲属关系,或者在同一个的应用程序中定义的activity组件可以使用不同的亲属关系。亲属关系会在两种情况下发挥作用:

1)负责激活activity组件的Intent对象中包含了FLAG_ACTIVITY_NEW_TASK标志。

2)被激活的activity组件的allowTaskReparenting属性被设置为“true”。

关于FLAG_ACTIVITY_NEW_TASK标志量

默认情况下,一个被激活的新activity会和负责激活它的那个activity组件存在于同一个任务栈中。但是若负责激活的Intent对象包含了FLAG_ACTIVITY_NEW_TASK标志,则系统会为存放那个即被激活的新activity寻找一个新的任务栈。此时,若已经存在了相同亲属关系的任务栈,则系统会直接将这个即被激活的新activity放入到这个任务栈中;否则系统会开始一个新的任务栈。

关于allowTaskReparenting属性

若一个activity组件的allowTaskReparenting被置为“true”,则当与这个activity有相同的亲属关系的任务栈被切换到前台的时候,这个activity会从当前存在的任务栈中移动到与其有相同的亲属关系的任务栈中。

若从用户的角度来看,一个.apk文件包含了一个以上的“应用程序”,那你可能要为那些activity组件指定不同的亲属关系。

2.启动模式

<activity>标签的launchMode属性可以设置为四种不同的模式:

“standard”(默认模式)

“singleTop”
android:launchMode="singleTop" 相当于每次都从这个ACITIVITY启动
“singleTask”
android:launchMode="singleTop" 和singleTop类似,不同于,每次启动后都在最上面
“singleInstance”

这几种模式的区别体现以下四点上:

1)当这个activity被激活的时候,会放入哪个任务栈。

对于“standard”和“singleTop”模式,这个新被激活的activity会放入和之前的activity相同的任务栈中――除非如前所述,Intent对象包含FLAG_ACTIVITY_NEW_TASK标志。

但“singleTask”和“singleInstance”模式则表示这个新被激活的activity不会放入已经存在的任务栈中,它会重新开启一个任务栈,并作为这个新的任务栈的根activity。

2)是否可以存在这个activity类型的多个实例。

对于“standard”和“singleTop”模式,可以有多个实例,并且这些实例可以属于不同的任务栈,每个任务栈也可以包含有这个activity类型的多个实例。

但“singleTask”和“singleInstance”模式则表示至多只可以存在这个activity类型的一个实例。又因为有第一点必须是根activity的限制,所以这意味着在同一时间,在手机上绝不会存在多于一个的由这个activity启动的任务栈。

3)包含此activity的任务栈是否可以包含其它的activity。

“singleInstance”模式表示包含此activity的任务栈不可以包含其它的activity。若此activity启动了另一个activity组件,那么无论那个activity组件的启动模式是什么或是Intent对象中是否包含了FLAG_ACTIVITY_NEW_TASK标志,它都会被放入另外的任务栈。在其它方面“singleInstance”模式和“singleTask”模式是一样的。

其余三种启动模式则允许包含此activity的任务栈包含其它的activity。

4)Whether a new instance of the class will be launched to handle a new intent.

对于默认的“standard”模式,每当响应一个Intent对象,都会创建一个这种activity类型的新的实例。即每一个activity实例处理一个intent。

对于“singleTop”模式,只有当这个activity的实例当前处于任务栈的栈顶位置,则它会被重复利用来处理新到达的intent对象。否则就和“standard”模式的行为一样。

正如第二点所说的,“singleTask”和“singleInstance”模式表示只能有一个实例,所以这个唯一的实例需要处理所有新到达的intent对象。又由于“singleInstance”模式的activity实例总是位于任务栈的栈顶,所以这样做很正常。但对于“singleTask”模式的acitvity,在其上面可能存在其它的activity组件,所以它的位置并不是栈顶,在这种情况下,intent对象会被丢弃。(虽然会被丢弃,但是这个intent对象会使这个任务栈切换到前台)

如果一个新到达的intent对象是被一个已经存在的activity组件来处理的,那么这个activity的onNewIntent(android.content.Intent)方法会被系统调用。

注意:若为了处理一个新到达的intent对象而创建了一个activity实例,则用户按下“BACK”键就会退到之前的那个activity。但若这个新到达的intent对象是由一个已经存在的activity组件来处理的,那么用户按下“BACK” 键就不会回退到处理这个新intent对象之前的状态了。

3.清理任务栈

如果一个任务栈在很长的一段时间都被用户保持在后台的,那么系统就会将这个任务栈中除了根activity以外的其它所有activity全部清除掉。从这之后,当用户再将任务栈切换到前台,则只能显示根activity了。

以上说的是默认模式,可以通过<activity>标签的一些属性来更改:

1)alwaysRetainTaskState属性

如果将根activity的alwaysRetainTaskState属性设置为“true”,则即便一个任务栈在很长的一段时间都被用户保持在后台的,系统也不会对这个任务栈进行清理。

2)clearTaskOnLaunch属性

如果将根activity的clearTaskOnLaunch属性设置为“true”,那么只有这个任务栈切换到了后台,那么系统就会将这个任务栈中除了根activity以外的其它所有activity全部清除掉。即和alwaysRetainTaskState的行为完全相反。

3) finishOnTaskLaunch属性

这个属性的行为类似于clearTaskOnLaunch,但是此属性作用于单个的activity对象,而不是整个任务栈。当这个任务栈切换到了后台,这个属性可以使任务栈清理包括根activity在内的任何activity对象。

这里也有另一种方法来使activity对象从任务栈中被移除。若Intent对象包含FLAG_ACTIVITY_CLEAR_TOP标志,并且在目标任务栈中已经存在了用于处理这个Intent对象的activity类型的一个实例,那么在任务栈中这个实例之上的所有activity实例会被移除。从而用于处理这个Intent对象的activity类型的那个实例会位于任务栈的栈顶,并用来处理那个Intent对象。若那个匹合的activity类型的启动模式是“standard”,则这个已经存在于任务栈中的匹合的activity类型的实例也会被移除,并且一个新的此类型activity的实例被创建并压栈来处理这个Intent对象。

FLAG_ACTIVITY_CLEAR_TOP这个标志经常和FLAG_ACTIVITY_NEW_TASK标志结合使用,这样结合使用的意思是在另一个任务栈中定位已经存在的匹合的activity类型的实例,并且让此实例位于栈顶。

4.启动任务栈

通过将一个activity类型的intent-filter的动作设置为“android.intent.action.MAIN”,类别设置为“android.intent.category.LAUNCHER”可以使这个activity实例称为一个任务栈的入口。拥有这种类型的intent-filter的activity类型的图表和名字也会显示在application launcher中。

第二个能力是很重要的:用户必须能够使一个任务栈切换到后台,也可以随时将其切换到前台。出于这个原因,使activity在启动时新开任务栈的启动模式(即“singleTask”和“singleInstance”模式)只应该被利用在拥有拥有“android.intent.action.MAIN”动作和“android.intent.category.LAUNCHER”类别的intent-filter的activity类型上。

类似的限制同样体现在FLAG_ACTIVITY_NEW_TASK标志上。如果这个标志使一个activity开始了一个新的任务栈,并且用户点击“HOME”键将其切换到了后台,则必须有某种方式使用户可以重新将那个任务栈切换到前台。一些实例(比如通知管理器),总是在外部的任务栈中开启一个activity,而不是其自身的任务栈,所以它们总是将FLAG_ACTIVITY_NEW_TASK标志放入Intent对象中,并将Intent对象传入startActivity()方法中。

对于在某些情况下,你不希望用户能够返回到某一个activity,那么可以通过设置<activity>标签的“finishOnTaskLaunch”属性为“true”来实现。

 

转自:http://blog.csdn.net/hellolinshoujie/article/details/6588855 转载请说明。

分享到:
评论

相关推荐

    Activity堆栈管理demo

    通过学习这个示例,开发者将能够更好地理解Activity堆栈的工作原理,从而优化应用的导航逻辑,提高用户体验。同时,掌握Activity管理工具类的使用也有助于提升开发效率,减少因误操作导致的问题。所以,深入研究...

    Android 中从activity1跳转到activity2再回到activity所经历的生命周期

    此时,Activity位于Activity堆栈的顶部,拥有用户焦点。这里使用`Log.i("activity", "onResume1")`进行记录。 当用户点击按钮触发Activity2的启动时: 4. **onPause()**: 当Activity失去用户焦点时调用。在我们的...

    Android activity堆栈及管理实例详解

    Activity堆栈,也称为任务堆栈,是一种“后进先出”(LIFO)的数据结构,用于管理Android应用中的Activity实例。每当用户启动一个新的Activity或者在现有Activity之间导航时,这些Activity都会按照它们被启动的顺序...

    Android利用Intent启动和关闭Activity

    【Android Intent 启动和关闭Activity】 在Android应用程序开发中,Intent是连接各个组件(如Activity、Service等)的关键桥梁,主要用于启动和关闭Activity。Intent不仅能够启动一个新的Activity,还能在Activity...

    Android深入理解Activity!

    Activity是Android应用开发中的核心组件之一,它是用户与应用程序交互的窗口。深入理解Activity,意味着我们需要探讨它的生命周期、启动模式、栈管理、Intent传递、UI更新以及与其他组件(如Service、...

    Android学习笔记-Activity篇

    1. 管理Task:Task是Android中的一系列Activity堆栈,代表用户的操作序列。每个Task有自己的Back Stack,用于存储按启动顺序排列的Activity。 2. 定义launch模式:在AndroidManifest.xml中,可以通过`android:...

    035_android_Activity入门和跳转

    8. Activity堆栈管理: Android系统使用任务(Task)和栈(BackStack)来管理Activity。新启动的Activity会被压入栈顶,当按下Back键时,栈顶的Activity会被弹出,呈现出栈底的Activity。理解这一机制有助于避免回退...

    Android-TopActivity展示当前app所处的最顶activity

    在Android应用开发中,了解和控制应用程序的Activity堆栈是非常重要的。"TopActivity"这个概念就是用来描述在当前运行的应用中位于最顶端的那个Activity。它代表着用户当前正在交互的界面,是用户可见并且可以直接...

    Android-Androidfragment堆栈控制器

    在Android应用开发中,Fragment是Android SDK提供的一种组件,它允许开发者在Activity中添加多个可交互的视图和逻辑单元。Fragment的设计理念是为了使大型应用更易于管理和维护,尤其是在处理多屏显示和不同设备尺寸...

    [Android开发从零开始].9.Activity高级学习

    它们决定了新Activity如何被创建和堆栈管理,例如,单任务模式会清除所有栈中处于它之上的Activity,而单实例模式则在整个应用中只创建一个Activity实例。 4. **Activity的回退栈**:Activity的回退栈是系统管理...

    Android高级应用源码-模拟Activity进出栈.rar

    - 在Android中,所有的Activity都被组织在一个任务(Task)中,任务是一个Activity的堆栈。当一个Activity启动时,它会被压入栈顶,而用户看到的就是栈顶的Activity。 2. **启动Activity** - 使用`Intent`启动...

    Android动画实例,不同Activity跳转

    例如,`FLAG_ACTIVITY_CLEAR_TOP` 可以清除目标Activity之上所有其他Activity,使目标Activity回到栈顶,这样可以实现特定的动画效果。 三、自定义动画 Android提供了一套完整的动画系统,包括属性动画(Property ...

    获取栈顶的activity

    Android的Activity是以任务(Task)为单位组织的,每个任务是一个Activity堆栈,新启动的Activity会被压入堆栈顶部,用户操作会从堆栈顶部的Activity开始。当用户按回退键或通过其他方式退出时,栈顶的Activity会被...

    android代码 Activity跳转

    不同模式会影响Activity的生命周期和堆栈管理,例如: 1. 标准模式(默认):每次启动新的Intent都会创建一个新的Activity实例。 2. 单任务模式:如果目标Activity已经在栈顶,不会创建新实例,而是调用onNewIntent...

    Android的Activity案例

    当用户在多个`Activity`之间切换时,Android系统会管理这些`Activity`的堆栈,称为任务(Task)。 **二、Activity生命周期** `Activity`有七个主要的生命周期回调方法,包括: 1. `onCreate()`:当`Activity`首次...

    Android开发 - Activity 初步

    在Android开发中,Activity是应用程序的基本构建块,它代表用户可见并可以与之交互的屏幕。这篇博客"Android开发 - Activity 初步"可能详细介绍了Activity的基础知识,包括它的概念、生命周期以及如何在代码中创建和...

    Android应用源码之9.Activity高级学习.zip

    本压缩包“Android应用源码之9.Activity高级学习.zip”提供了一套关于Activity高级使用的源码示例,旨在帮助开发者深入理解并熟练掌握Activity的相关特性。 1. **生命周期管理**:Activity的生命周期是其核心概念,...

    Android中获取系统内存信息以及进程信息

    在Android系统中,开发者可以通过Android提供的API来获取系统的内存信息以及正在运行的进程状态。这一功能主要涉及到`ActivityManager`类的使用。`ActivityManager`是Android SDK中的一个关键组件,它提供了对系统...

    android Activity生命周期 详解

    Android使用"Activity堆栈"(也称为任务栈)的概念来管理Activity。每次启动新的Activity,它都会被压入堆栈的顶部,当前的Activity移到下面。当用户按下Back键,堆栈顶部的Activity被弹出,堆栈中的下一个Activity...

Global site tag (gtag.js) - Google Analytics