`

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

    该资源的源码分析地址:http://blog.csdn.net/u011862733/article/details/51788634

    Android activity堆栈及管理实例详解

    主要介绍了Android activity堆栈及管理实例详解的相关资料,非常不错,具有参考借鉴价值,对android activity堆栈相关知识感兴趣的朋友一起学习吧

    Android Activity生命周期和堆栈管理的详解

    主要介绍了Android Activity生命周期和堆栈管理的详解的相关资料,需要的朋友可以参考下

    Activity-:Activity堆栈式管理

    import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import com.ideacode.news.logic.IdeaCodeActivity; public class AppManager { private static Stack ...

    Android自主学习项目报告(一).doc

    不要在让transactions在其他的Activity生命周期函数提交,如onActivi tyResult()、onStart()和onResume() 自己在学习过程中总结的知识点 (3)Android体系结构和Android项目目录 Android是基于Linux内核的软件平台和...

    android判断一个Activity是否处于栈顶的实例

    实际开发中我们需要很多情况需要判断某个activity是否位于栈顶,也许会给新的小伙伴带来困扰,那么直接上代码吧,也没几行 /** * * 判断某activity是否处于栈顶 * @return true在栈顶 false不在栈顶 */ private...

    Android判断当前栈顶Activity的包名代码示例

    主要介绍了Android判断当前栈顶Activity的包名代码示例,分享了相关代码,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

    android 开发技巧合集

    2.1.5.Actvity 堆栈 18 2.1.6、Intent对象调用Activity实例 19 2.1.7、Activity透明 21 2.1.8、一次性关闭所有的Activity 22 2.1.9、PreferenceActivity 用法 22 2.1.10、Dialog风格的Activity 23 2.1.11、横竖屏...

    退出Android程序时清除所有activity的实现方法

    本文实例讲述了退出Android程序时清除所有activity的方法。分享给大家供大家参考,具体如下: 在一个项目中,要退出android程序,试了restartPackage、 killBackgroundProcesses 、通过异常并在Application的子类中...

    Android调用堆栈跟踪实例分析

    本文实例讲述了Android调用堆栈跟踪的方法。分享给大家供大家参考。具体如下: Android开发中,我们也会经常遇到段错误,也就是SIGSEGV(11),这个时候libc的backtrace会打印出对应的堆栈信 息,而你看到的仅仅是...

    启动服务、启动线程、得到任务堆栈列表的简单代码

    其实我只想得到任务堆栈里的activity的包名。找好久才找到相关的。 文件包含两个java文件和一个AndroidManifest.xml(启动Service,和申请相关权限,这里的内容很重要!)。 注意把文件里面的包名、类名换成你自己的...

    新版Android开发教程.rar

    Android 进一步推进了 " 随时随地为每个人提供信息 " 这一企 业 目标的实现。 � Open Handset Alliance 汇集了多家业界巨头。运营商如: China Mobile 、 NTT DoCoMo 、 Vodafone 、 T-M obile 等;设备制造商如 ...

    Activity基类

    统一的上下文对象 对context进行初始化,并将当前的Activity加入到堆栈中便于管理 初始化控件绑定事件 初始化数据 统一的返回方法 设置默认的退出效果

    android中Activity横竖屏切换的那些事

    跟activity堆栈中的下面一个activity的方向一致 landscape 横屏方向,显示的宽比高长 portrait 竖屏方向,显示的高比宽长 sensor 由设备的物理方向传感器决定,如果用户旋转设备,这屏幕就会横竖屏切换 ...

    android实习报告(1).doc

    运行态是在 屏幕台前位于当前任务堆栈的顶部,即获取焦点的Activity。暂停信息是指失去了焦点 但对于用户仍可见,此状态下当程序处于低内存是仍有可能被消除。停止状态是指完全 被另一个Activity覆盖,但他仍然保留...

    堆栈退出ancivity实例

    通过堆栈实现删除多个activity,比如现有A,B,C,D 4个activity,一次从进入到打开,同时进入堆栈。在操作完D后,可以删除堆栈中的activity。达到了删除多个activity的功能。这种功能在运用开发过程中时常碰到。

    Pilot:适用于Android的android。*解耦的应用程序堆栈

    单项Activity申请 A(被动)薄壁View基础架构 android.* -less应用程序导航(即Controller-&gt; Controller) 抽象的堆栈 基于堆栈的数据范围 使用任何类型的MV *方法 为什么 更清晰的解耦代码 出于多种原因,人们...

    WindowManagerService服务是如何以堆栈的形式来组织窗口

    我们知道,在Android系统中,Activity是以堆栈的形式组织在ActivityManagerService服务中的。与Activity类似,Android系统中的窗口也是以堆栈的形式组织在WindowManagerService服务中的,其中,Z轴位置较低的窗口...

Global site tag (gtag.js) - Google Analytics