android 怎么自定义任务栈,Android中的Activity详解--启动模式与任务栈

目录

Activity

生命周期

任务栈

启动模式

Intent Flag

taskAffinity属性

1.Activity

activity的简单介绍就不写了,作为最常用的四大组件之一,肯定都很熟悉其基本用法了。

2.生命周期

首先,是都很熟悉的一张图,即官方介绍的Activity生命周期图.

35fd45135d99

Activity生命周期图

情景:打开某个应用的的FirstActivity调用方法如下:

由于之前已经很熟悉了,这里就简单贴一些图。

35fd45135d99

Paste_Image.png

按下返回键:

35fd45135d99

Paste_Image.png

重新打开并按下home键:

35fd45135d99

Paste_Image.png

再重新打开:

35fd45135d99

Paste_Image.png

在其中打开一个DialogActivity(SecondActivity)

35fd45135d99

Paste_Image.png

按下返回:

35fd45135d99

Paste_Image.png

修改SecondAcitvity为普通Activity,依旧是上述操作:

35fd45135d99

Paste_Image.png

这里强调一下onSaveInstanceState(Bundle outState)方法的调用时机:

当Activity有可能被系统杀掉时调用,注意,一定是被系统杀掉,自己调用finish是不行的。

测试如下:FirstActivity启动SecondActivity:

35fd45135d99

Paste_Image.png

如果SecondActivity是android:theme="@android:style/Theme.Dialog"那么:

35fd45135d99

Paste_Image.png

如果FirstActivity启动SecondActivity后自己调用了finish方法:

35fd45135d99

Paste_Image.png

也就是说,只要一个Activity转为后台,那么就会调用此方法,因为其有可能被系统杀掉,其中存的Bundle对象就是用来存储数据的,这个也就是onCreate方法中Bundle对象参数savedInstanceState的由来。

3.Acitvity任务栈

一个App会包含很多个Activity,多个Activity之间通过intent进行跳转,那么原始的Activity就是使用栈这个数据结构来保存的。

Task

A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (theback stack), in the order in which each activity is opened.

即若干个Activity的集合的栈表示一个Task。

当App启动时如果不存在当前App的任务栈就会自动创建一个,默认情况下一个App中的所有Activity都是放在一个Task中的,但是如果指定了特殊的启动模式,那么就会出现同一个App的Activity出现在不同的任务栈中的情况,即会有任务栈中包含来自于不同App的Activity。

4.启动模式

standard

标准模式,在不指定启动模式的情况下都是以此种方式启动的。每次启动都会创建一个新的Activity实例,覆盖在原有的Activity上,原有的Activity入栈。

测试如下:在FirstActivity中启动FirstActivity:

35fd45135d99

Paste_Image.png

当只有一个FirstActivity时堆栈情况:

35fd45135d99

Paste_Image.png

当在FirstActivity中启动FirstActivity时堆栈情况:

35fd45135d99

Paste_Image.png

这就很显然了,任务栈中一共有两个FirstActivity,即表示每次启动FirstActivity都是创建了一个新的实例。

singleTop

此种模式下,Activity在启动时会进行判断,如果当前的App的栈顶的Activity即正在活动的Activity就是将要启动的Activity,那么就不会创建新的实例,直接使用栈顶的实例。

测试,设置FirstActivity为此启动模式,多次点击FirstActivity中的启动FirstActivity的按钮查看堆栈情况:

(其实点击按钮没有启动新Activity的动画就可以看出并没有启动新Activity)

35fd45135d99

Paste_Image.png

果然,堆栈中只有一个FirstActivity

如果我在FirstActivity中启动了SecondActivity,此时FirstActivity不就不在栈顶了么,此时我再启动FirstActivity会怎样呢?

测试如下:

35fd45135d99

Paste_Image.png

很好的验证了,只有在栈顶时,才不会创建新实例。

这种启动模式很适用于接收到消息之后进行显示的界面,总不能每次来消息都创建新实例,那一次来个十几条消息岂不是爆炸了。

在此种模式下,在不创建新的实例的时候,会调用onNewIntent()方法。

总结:栈顶的Activity只会有一个实例,在栈顶的情况下重复启动该Activity只会复用该Activity,而不会创建一个新的,除了栈顶的Activity外,其他的和standard类似,每次启动都会被创建一个新的实例。

onNewIntent(Intent intent)方法介绍

官方解释如下:

This is called for activities that set launchMode to "singleTop" in

* their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP}

* flag when calling {@link #startActivity}. In either case, when the

* activity is re-launched while at the top of the activity stack instead

* of a new instance of the activity being started, onNewIntent() will be

* called on the existing instance with the Intent that was used to

* re-launch it.

*

*

An activity will always be paused before receiving a new intent, so

* you can count on {@link #onResume} being called after this method.

*

*

Note that {@link #getIntent} still returns the original Intent. You

* can use {@link #setIntent} to update it to this new Intent.

*

* @param intent The new intent that was started for the activity.

大意就是:

对于使用singleTop启动或Intent.FLAG_ACTIVITY_SINGLE_TOP启动的Activity,当该Activity被重复启动(注意一定是re-launched,第一次启动时不会调用)时就会调用此方法。

且调用此方法之前会先暂停Activity也就是先调用onPause方法。

而且,即使是在新的调用产生后此方法被调用,但是通过getIntent方法获取到的依旧是以前的Intent,可以通过setIntent方法设置新的Intent。

方法参数就是新传递的Intent.

singleTask

1.如果是同一个App中启动某个设置了此模式的Activity的话,如果栈中已经存在该Activity的实例,那么就会将该Activity上面的Activity清空,并将此实例放在栈顶。

测试:SecondActivity启动模式设为singleTask,启动三个Activity:

35fd45135d99

Paste_Image.png

然后在ThirdActivity中启动SecondActivity(注意不是返回,而是启动):

35fd45135d99

Paste_Image.png

果然,SecondActivity上的ThirdActivity被清掉了

2.如果是其他应用的Activity启动的本应用中此Activity,那么

- 本应用未启动时,在另一个应用的ActivityY中启动SecondActivity:

35fd45135d99

Paste_Image.png

显然,此时这个SecondActivity是在一个单独的任务栈中的,且是处于前台的,按下返回键,SecondActivity结束,返回到ActivityY。

- 本应用已经启动了,在后台运行,任务栈中是FirstActivity和SecondActivity,在另一个应用的ActivityY中启动此Activity,此时任务栈的状态:

35fd45135d99

Paste_Image.png

两个任务栈,每个栈中都有两个Activity。

注意,此时如果按下返回键,会出现什么情况呢,到底是返回到ActivityY,还是返回到FirstActivity?

结果如下:

35fd45135d99

Paste_Image.png

前台Activity竟然变成了FirstActivity!继续按下返回键,就会返回到ActivityY,ActivityX,然后退出。

也就是说,在ActivityY启动了SecondActivity时,连带着SecondActivity的任务栈也被带到了前台。

那么我不禁要问了,如果SecondActivity启动模式是默认的,会不会是此种情况呢?,其实按照我们前面学的,按照分析的话,应该是SecondActivity在ActivityY所在的App所对应的任务栈中创建一个新的实例,跟原本的SecondActivity所在后台任务栈没有一毛钱关系。

- 本应用已经启动了三个Activity,任务栈中是FirstActivity和SecondActivity和ThirdActivity,此时再由ActivityY启动:

那么稍微思考一下就可以肯定运行结果跟上面是完全相同的,因为在跳转到SecondActivity时,其上面的Activity已经被清空了。

singleInstance

这个模式就很好记,以此模式启动的Activity会存放在一个单独的任务栈中,且只会有一个实例。

测试:SecondActivity启动模式设为singleInstance

FirstActivity->SesondActivity->ThirdActivity->SecondActivity->ThirdActivity

结果:

35fd45135d99

Paste_Image.png

显然,启动了两次ThirdActivity任务栈中就有两个实例,而SecondActivity在另外一个任务栈中,且只有一个。

5.Intent Flag设置启动模式

在使用Intent启动一个Activity时可以设置启动该Activity的启动模式:

这个属性有很多,大致列出几个:

Intent.FLAG_ACTIVITY_NEW_TASK

每个启动的Activity都在一个新的任务栈中

Intent.FLAG_ACTIVITY_SINGLE_TOP

singleTop

Intent.FLAG_ACTIVITY_CLEAR_TOP

singleTask

Intent.FLAG_ACTIVITY_NO_HISTORY

用此种方式启动的Activity,在它启动了其他Activity后,会自动finish.

6.taskAffinity属性

官方文档介绍如下:

The task that the activity has an affinity for. Activities with the same affinity conceptually belong to the same task (to the same "application" from the user's perspective). The affinity of a task is determined by the affinity of its root activity.The affinity determines two things — the task that the activity is re-parented to and the task that will house the activity when it is launched with the FLAG_ACTIVITY_NEW_TASK flag.

By default, all activities in an application have the same affinity. You can set this attribute to group them differently, and even place activities defined in different applications within the same task. To specify that the activity does not have an affinity for any task, set it to an empty string.

If this attribute is not set, the activity inherits the affinity set for the application (see theelement's taskAffinity.

The name of the default affinity for an application is the package name set by theelement.

大意如下:

这个属性表示的是一个Activity对任务栈的亲和度。有相同的affinity的Activity属于同一个Task,即affinity相同的Activity会被加入同一任务栈。一个任务栈的affinity由其affinity值确定或是其根Activity的affinity确定。这个属性决定两件事,①Activity被re-parented时的任务栈,②以FLAG_ACTIVITY_NEW_TASK启动的Activity所在的任务栈。

默认情况下,同一个应用内的所有的Activity都拥有相同的affinity,你可以通过设置这个值来给Activity分组,甚至将不同应用的Activity放在相同的任务栈中。为了表明一个Activity对任何一个任务栈都不具有亲和力,那么将其设为空字符串。

如果这个值没有设置,那么就默认使用application标签下的这个值。

默认的affinity值为manifest标签下设置的包名。

这样看来的话,通俗易懂的讲,就是给每一个任务栈起个名,给每个Activity也起个名,在Activity以singleTask模式启动时,就检查有没有跟此Activity的名相同的任务栈,有的话就将其加入其中。没有的话就按照这个Activity的名创建一个任务栈。

测试:在App1中设置SecondActivity的taskAffinity为“gsq.test”,App2中的ActivityX的taskAffinity也设为“gsq.test”

FirstActivity->SesondActivity->home->ActivityX

任务栈信息如下:

35fd45135d99

Paste_Image.png

结果很显然了。

测试:在上述基础上,在ActivityX中进行跳转到ActivityY,ActivityY不指定启动模式和taskAffinity。结果如下:

35fd45135d99

Paste_Image.png

发现ActivityY在gsq.test任务栈中,这是由于其启动模式是Standard,也就是在启动这个Activity的所在的任务任务栈中。

再将ActivityY指定启动模式singleTask:

35fd45135d99

Paste_Image.png

这样就没问题了,ActivityY在一个新的任务栈中,名称为包名。

这时从ActivityY跳转到SecondActivity,那应该是gsq.test任务栈只有SecondActivity,ActivityX已经没有了。因为其启动模式是singleTask,在启动它时发现已经有一个实例存在,就把它所在的任务栈上面的Activity都清空了并将其置于栈顶。

还有一点需要提一下,在上面,FirstActivity是App1的lunch Activity,但是由于SecondActivity并没有指定MAIN和LAUNCHER过滤器,故在FirstActivity跳转到SecondActivity时,按下home键,再点开App1,回到的是FirstActivity。

大致就先写这么多吧,好像有点长,废话有点多,估计也有错别字,不要太在意~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429682.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL Server--疑难杂症之坑爹的Windows故障转移群集

-- 估计是春节前最后一次写博客,也估计是本年值班最后一次踩雷,感叹下成也SQL SERVER,败也SQL SERVER。 -- 场景描述: 操作系统版本 :Windows Server 2012 数据中心版本 数据库版本 :SQL SERVER 2012 企业版…

android handle 阻塞,Android全面解析之Handler机制:常见问题汇总

主线程为什么不用初始化Looper?答:因为应用在启动的过程中就已经初始化主线程Looper了。每个java应用程序都是有一个main方法入口,Android是基于Java的程序也不例外。Android程序的入口在ActivityThread的main方法中:// 初始化主线…

UML中的6大关系(关联、依赖、聚合、组合、泛化、实现)

UML定义的关系主要有六种:依赖、类属、关联、实现、聚合和组合。这些类间关系的理解和使用是掌握和应用UML的关键,而也就是这几种关系,往往会让初学者迷惑。这里给出这六种主要UML关系的说明和类图描述,一看之下,清晰明…

性能调优-硬盘方面,操作系统方面,文件系统方面

硬盘对数据库性能的影响 传统机械硬盘 当前大多数数据库使用的都是传统的机械硬盘。机械硬盘的技术目前已非常成熟,在服务器领域一般使用SAS或SATA接口的硬盘。服务器机械硬盘开始向小型化转型,目前已经有大量2.5寸的SAS机械硬盘。 机械硬盘有两个重要的…

chrome Android 80,Chrome OS 80将为Chromebook带来侧载Android应用的支持

如需体验这项功能,需在启动 Crostini 容器时加上一行特殊的命令 —— 从 Chromebook 命令行启动时,请加上 –enable-features ArcAdbSideloading 。最终,我们希望这回成为一项明示的标记(flags)功能。如变更日志所述,用户可通过托…

android 日历仿IOS,基于Android week view仿小米和iphone日历效果

前言最近由于项目需求,要做一个仿小米日历的功能,下面显示一天的日程,header以周为单位进行滑动,github上找了很久也没有找到合适的,但找到一相近的开源项目Android-week-view,它不是我们项目所需要的效果&…

1、管理员登录中间件和注销

1、根据session去判断用户是否登录,登录后才可以进index首页,否则返回login页面,借助中间件 (1)修改路由 Route::group([middleware > [web,admin.login],prefix>admin,namespace>Admin], function () { //注册一个中间件admin.logi…

HTML阅读打开点击不了,如何让网页文章中的代码可以点击运行

在网页中运行代码HTML5学堂:很多代码网站当中,都会提供运行代码段功能,便于查看代码效果,那么这个是如何实现的呢?一起来看一下——如何在网页中运行代码。HTML5学堂-刘国利said:应该是在2013年的时候&…

html留言回复评论页面模板,HTML5实现留言和回复的页面样式

这篇文章主要介绍了用HTML5如何实现留言和回复样式,需要的朋友可以参考下具体就不做详细讲解了,直接上代码:web开发-webkfa.com*{margin:0;padding:0;-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */-webkit-t…

html5列表菜单特效,HTML5 SVG汉堡包菜单按钮分段动画特效

这是一款效果非常炫酷的HTML5 SVG汉堡包菜单按钮分段动画特效。该菜单按钮特效在用户点击汉堡包按钮时,按钮会分割为多段,并旋转变形为关闭按钮的状态。当再次点击该按钮时,它会逆向变形为汉堡包图标。该特效是基于Segment.js插件(一款可以只…

计算机选修课学什么,计算机专业都学什么 主要课程有什么

计算机专业的主要学习内容有什么呢,都开设哪些课程呢,下面小编为大家提供计算机专业主要学习内容,仅供大家参考。计算机专业主要学习内容一、数学类主要课程:高等数学、线性代数、离散数学、概率论、数理统计二、语言类主要课程&a…

excel取html文本长度,excel字符长度 怎么计算excel里的字符串的长度

请教:在EXCEL中如何统计字符长度?打开excel文件,确定需要编辑的内容选择功能区的“公式”功能在公式中选择“LEN”功能在text中选择需要编辑的单元格 7、点击“确定” 8、系统自动计算出了单元excel中怎么判断字符串的长度在Excel中可以使用两…

Java虚拟机(JVM)默认字符集详解

Java中对字符串等进行转换字节数组时, 需要根据字符集编码来进行转换, 当不显示的指定字符集编码时(如: "测试".getBytes()), 会使用Charset.defaultCharset()获取到的字符集编码进行转换! 相关代码如下: 上面的代码可以看出, 在JVM中defaultCharset()是在初始化阶段…

计算机本地用户删除后怎么恢复,Default User文件夹被删了怎样恢复

满意答案opposities2013.06.06采纳率:80% 等级:24已帮助:17327人1、开机后出现“Windows 不能加载本地存储的配置文件。此问题的可能原因是安全权限不足或本地配置文件损坏。如果此问题持续存在,请与您的网络管理员联系。倒数3…

08-SSH综合案例:前台用户模块:注册页面的前台JS校验

这个是MyEclipse设置的问题 把设置去掉就没问题了。 你也可以在每一个input后面加个span来显示提示的信息。这些东西也要提交到后台,后台也是要对这些东西进行校验的。转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/6377756.html

计算机管理员无法创建密码,找到电脑管理员的密码

轻松找回遗忘的WinXP管理员密码很多“不拘小节”的朋友在使用电脑时,经常是昨天改了Windows XP帐户密码,今天便忘记了内容,把自己锁在“门外”的情况时有发生。对此,大多数朋友只能痛苦的去重新安装系统。其实如果你有以下的条件&…

clientWidth、clientHeight、offsetWidth、offsetHeight以及scrollWidth、scrollHeight

clientWidth、clientHeight、offsetWidth、offsetHeight以及scrollWidth、scrollHeight是几个困惑了好久的元素属性,趁着有时间整理一下 1. clientWidth 和 clientHeight 网页中的每个元素都具有 clientWidth 和 clientHeight 属性,表示可视区域的宽高&…

API文档工具-Swagger的集成

最近安装了API文档工具swagger,因为Github上已有详细安装教程,且安装过程中没有碰到大的阻碍,所以此文仅对这次安装做一份大致记录 相关网站 Swagger 官方地址:http://swagger.wordnik.com Github安装详解【springmvc集成swagger】…

计算机翻译辅助工具安卓版,计算机辅助翻译软件

OmegaT是一款电脑翻译软件,此软件能够帮助用户对一些机器专业语言进行快速翻译,目前软件支持任何Java的操作系统,用户无需担心系统不支持的问题。另外,软件可以在任意目录中搜索所支持的格式的文件,翻译速度快、准确性…

计算机应用基础试模块5ACCSE,2015年计算机二级《Access》上机最后冲刺卷(1)

二、基本操作题41在考生文件夹下的“Acc1.mdb”数据库中已建立表对象“职工”。试按以下操作要求,完成对表“职工”的编辑修改和操作:(1)将“职工号”字段改名为“编号”,并设置为主键。(2)设置“年龄”字段的有效性规则为“年龄>20”。(3…