Activity的启动模式解惑

在做一个需求的时候需要设置一个activity的启动模式,由于之前的启动模式是默认的standard ,怕出问题,所以没有在AndroidManifest.xml文件设置启动方式,需要代码设置,但是却遇到了一些小问题,在讲问题之前,先回顾一下activity的四种启动方式

  • standard 方式:标准模式,这是系统默认是模式,如果你没有指定特定的启动模式的话,默认该方式。每次启动一个Activity都会重新创建一个新的Activity,不管这个实例是否已经存在。假设有A,B两个页面,A跳转到B,B再跳转到B ,那么这个任务栈里将会存在两个B Activity;

  • singleTop:栈顶复用模式。在这种模式下,如果栈中存在当前要跳转的且在栈顶的实例,一定要是栈顶,那么该实例将不再创建,而是直接复用。假设一个栈中有ABCD四个页面,当D 要跳转到D 的时候,是不会创建新的实例的,因为D实例存在且在栈顶,栈里的情况依旧是ABCD,但是如果D要跳转到C ,虽然栈中存在C 但是因为该实例没有在栈顶,所以仍然会创建新的实例,最后的效果为ABCDC.

  • singleInstance : 单实例模式,是一种加强的singelTask模式吧,该模式只能在AndroidManifest文件里设置,不能在代码里设置,我曾经找了很久设置的方法,但是并没有找到。这种模式下,你跳转的Activity会独立于原有的栈,并在新开辟的栈中进行实例的复用。举个例子:假设有ABCD四个页面,D页面以singleInstance 方式跳转到E页面,然后E页面再以正常模式跳转到F页面,最终的效果是A—>B—>C—->D↗E↘F,我用箭头标明了一下他的不同之处,因为E是独立于ADCDF存在的,也就是说,如果你在F页面点击返回按钮,顺序是F—>D—>C—>B—A,并没有E什么事情,因为他们并没有在同一个栈中,没有半毛钱关系。

    FLAG_ACTIVITY_NEW_TASK 和singleTask真的一样吗

说完常见的启动方式,现在说一下我遇到的问题,在博客里或者书上,都有说到singleTask等价于FLAG_ACTIVITY_NEW_TASK,只不过一个是AndroidManifest文件里设置方式,一个是代码里的设置方式,好像大家都默认这样。官方文档也是这么说的
这里写图片描述
链接 https://developer.android.com/guide/components/tasks-and-back-stack.html
之前我也说过,由于我们任务的需求,以及原有的启动模式,我只能在代码里修改特定页面跳转到该页面的启动方式,好设置代码,第一个页面
这里写图片描述

第二个页面
这里写图片描述

看着很完美,没有什么问题,但是在实际运行过程中,却跟我们的理解不一样。要知道singleTask是一种单例模式,只要你请求的栈中存在该实例,是不会创建新的实例的,会复用,也就是A-B B跳B 无论跳多少次,栈里只有AB.但是,看效果
这里写图片描述
这完全和standard没有任何区别嘛!
(singelTask方式会复用单例同时走OnNewIntent方法),但是在代码里我们并没有看到 Toast.makeText(SecondActivity.this,"onNewIntent被调用",Toast.LENGTH_SHORT).show(); 的执行,并且返回的时候返回了好多次,明显没有复用,难道说明启动方式有问题,或者我们的理解有问题?
开始测试,接下来,我们代码不这么设置,我们在AndroidManifest设置默认的启动方式为singleTask,代码不贴了,上效果图
这里写图片描述
可以看到,我点了很多次跳转到B页面,而系统并没有创建新的实例,只是复用了该实例且调用了OnNewIntent方法,奇葩!

接下来我们回想一下singleTask要复用的条件1,是要存在该实例,2,该已存在的栈正好和你要跳转的栈是同一个栈。
第一条肯定是存在的了,因为就活生生在我们面前,难道是第二条不符合?接下来我们看看我们要跳转的栈和当前B所在的栈是不是同一个栈,方法很简单,获得迪昂前页面的taskID即可,代码如下:

mJumpView.setText(this.getTaskId()+"");

获取到当前栈的id,看是否一样即可,但是结果很不幸,是完全一样的,

这里写图片描述

一下子陷入了僵局。后来通过查阅资料,发现FLAG_ACTIVITY_NEW_TASK是需要与TaskAffinity一起使用的,这个参数标识了一个Activity所需要栈的名字,默认情况下就是该应用的包名,你可以另起炉灶,但是不能和包名相同,因为那样和没设置一样了。
既然这样,那我测试一下,我在AndroidManifest设置了一下这个属性这里写图片描述
结果很不幸,点击secondActivity后没有任何反映应了。。
taskAffinity这个属性 按照我的理解就是标记了一个任务栈,以该属性并且以singleTask模式启动,启动的activity都会在该任务栈里,有则复用,没有则创建新的并压入该栈中。

总结,不管是官方文档还是《android 开发艺术探索》这本书,都有说FLAG_ACTIVITY_NEW_TASK 和singleTask效果相同,但是测试下来并不一样,可能是我忽略了一些重要的点,由于忙着其他任务,同时要记录一下自己的所想,所以还没有太深入的研究,如果有哪位大牛路过,恳请指正~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值