android7.0 service,Android7.0系统bug(Service打开Activit无需加FLAG_ACTIVITY_NEW_TASK)

先扔代码,在讨论问题

MainActivitya5521a3594249f108ba210f02c0ab0e8.png

MyService

d24db12d0552079ca2cd3e46c05847ec.png

ThreeActivity44201d1d6b18807b70ea94b29c743648.png

相信大家已经发现问题了,就是在MyService中的

startActivity(new Intent(this, ThreeActivity.class)); 会报错。但是真的会报错吗?请看下面的效果

三星盖乐世C5效果7f5dd0d8d48a7740c76d602b2d822483.gif

vivo Y67A效果

1605e149c65ab93188c6e436d5850eae.gif

ce0a91f8c0722402663a2f9ce43d2a84.png

发现了吗?Android7.0上这段代码是没有问题的,也就是说,Android7.0版本上是可以在不是设置

FLAG_ACTIVITY_NEW_TASK的。而Android6.0版本上是不行的。那么这到底是不是个bug呢?接下来咱们从源码入手看下到底是什么原因。

我们知道像Service,BroadcastReceiver,Application等都是ContextWrapper的子类,调用startActivity()时会调用ContextWrapper的startActivity()

0a230b2fe4e8c2f33b1918ce9ab951ec.png

这个mBase就是ContextImpl.这个ContextImpl是在ActivityThread里赋值的:

Activity-->ActivityThread::performLaunchActivity()

Service-->ActivityThread::handleCreateService()

Application-->LoadedApk::makeApplication()

有兴趣的同学自行查看,这里就不讨论了

接下来我们先看下ContextImpl的startActivity()

低版本 Android4.4 api-19(截止到Android6.0)

8a474591b03b6bae4e403b1a51ab3e8c.png

很简单,就是非Activity的Context启动Activity时如果不给intent设置FLAG_ACTIVITY_NEW_TASK就会报错

高版本Android8.0 api-27(Android7.0加入)

38ead2e411acbcb6030d08a582176ded.png

跟旧版本的代码相比,这里多了个options的非空判断(options != null),关键就在这里.

由于这里options传的就是null,于是就跳过了这个异常.那么,这里的逻辑是"&&",有一个不成立就算失败,那么我们不设置FLA

这里的注释翻译下是:从Activity外部(Service,BroadcastReceiver,Application等)不设置FLAG_ACTIVITY_NEW_TASK是不能启,可是上面的代码明显没有指定task的id就能成功启动了啊,这应该算Android系统的一个bug吧.(看来谷歌的开发和我们一样,都有迷糊的时候)

所以Android7.0和8.0版本应该都有这个bug(由于我这里没有8.0的手机,希望各位有条件的小伙伴测试下这个问题)

后续Android9.0代码已修复(&&options != null 已改为 &&options == null)

85b2e9fe9d23fe6ae6cfe1e5da2dcf7d.png

参考:作者 十蛋斯坦 《刨根问底Service为什么能启动Activity》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值