我以为发现了Android 14系统中的一个bug,然而...

这篇具有很好参考价值的文章主要介绍了我以为发现了Android 14系统中的一个bug,然而...。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。

今天来跟大家探讨一个Android 14很细节的知识点。

事情的起因是这样的,某天工作群里,我看到我们部门的同事guting发了这样一条消息。

我以为发现了Android 14系统中的一个bug,然而...,Android疑难解析,android,bug,kotlin,jetpack

我看到这条消息之后的第一感觉就是,貌似和我印象中Android 14的行为并不一致。

因为没有任何错误日志可以观察到这种现象是不应该的,我印象中用法不正确的话是会直接导致应用程序崩溃。

但其实我自己也记不太清楚了,我写Android 14新特性的文章已经是去年3月份发布的了。于是我还特意找到了 Android 14 Developer Preview一览 这篇文章重新又学习了一遍。

为了这篇文章大家能够看得明白,所以我把当时写的Android 14在涉及隐式Intent限制变动的部分摘抄出来,跟大家再快速过一遍。

首先这项改动只针对targetSdkVersion指定到34(Android 14)及以上的App才生效。

我们先来看一下如下代码:

<activity
    android:name=".PickPhotoActivity"
    android:exported="false">
    <intent-filter>
        <action android:name="com.example.action.PICK_PHOTO" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

这里定义了一个PickPhotoActivity,用于选择用户需要的照片。注意这个Activity的exported属性是false,说明它是仅供内部使用的。

那么如果我们想要调用这个Activity来选择照片,可以怎么写呢?由于它能够响应com.example.action.PICK_PHOTO这个自定义action,很容易就能写出如下代码:

val intent = Intent("com.example.action.PICK_PHOTO")
context.startActivity(intent)

这是用隐式Intent来启动Activity的写法。这段代码确实可以正常工作,但是大家有没有想过一个问题,假如现在你的手机上有另外一个App,它的AndroidManifest.xml里是这么写的:

<activity
    android:name=".HookPickPhotoActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.action.PICK_PHOTO" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

可以看到,它也能够响应com.example.action.PICK_PHOTO这个action,并且它的exported属性是true,说明它是允许外部调用的。

那么此时你还使用上述的代码来选择照片,启动的到底是谁的Activity?

这种情况下,系统也不知道你到底想要启动谁,所以就只能弹出一个对话框,让用户自己去选择。

由此可以看出,恶意软件在这种场景下是有空子可以钻的,因为必然会有用户选择错误。

那么为了解决这方面的安全隐患,Android 14对隐式Intent的使用做出了更多的限制。

当你的targetSdkVersion指定到了34及以上,再使用上述代码去启动Activity,系统就会抛出异常。

这是因为,PickPhotoActivity的exported属性是false,说明它是仅供内部使用的。仅供内部使用的组件,在用隐式Intent启动它的时候一定要给Intent指定当前App的包名,转换成显式Intent才行,如下所示:

val intent = Intent("com.example.action.PICK_PHOTO")
intent.package = context.packageName
context.startActivity(intent)

这样的话,对于系统来说就不会存在二义性,它会非常明确地知道要去启动哪一个Activity,从而进一步提升了安全性。

相信看完这段讲解之后,大家已经能理解Android 14在限制隐式Intent方面的变动了。

唯一的问题就是,我所使用的上述示例,在没有明确指定当前App包名的情况会崩溃,而我的同事guting却反馈说是没有任何错误日志可以观察到。

我又去Android的官方文档上面做了二次核对,官方文档里也有明确提到,用错的情况下是会抛出异常的。

我以为发现了Android 14系统中的一个bug,然而...,Android疑难解析,android,bug,kotlin,jetpack

所以问题到底出在哪里呢?

我和guting做了线下沟通,并且看了看他所写的代码。

代码没看出任何毛病,但是和我上述代码示例中不同的地方在于,我用Intent触发的行为是startActivity,而他用Intent触发的行为是sendBroadcast。

难道是在Android 14上Activity和BroadcastReceiver的行为会有不一致?我们又去查看了一遍官方文档:

我以为发现了Android 14系统中的一个bug,然而...,Android疑难解析,android,bug,kotlin,jetpack

文档里确实没提到过Activity或BroadcastReceiver的字眼,它用的是components。既然是components,那么就应该包含Activity、Service、BroadcastReceiver和ContentProvider的。所以刚才的猜想不成立。

后来我们又尝试了一下使用隐式Intent启动Serivce,在不指定包名的情况下也会崩溃。只有发送广播时不会崩溃,且这条广播是收不到的,相当于广播莫名其妙丢失了。

所以我又做了另外一个猜想,或许这是触发了广播某些其他的特殊规则,而和Android 14的这项新特性并无关系。

我去翻了翻《第一行代码 第3版》中对广播这部分的解释,里面确实有提到,从Android 8系统开始,静态注册的BroadcastReceiver,如果想要接收得到广播消息,Intent中必须明确指定App的包名才行。

但是我和guting检查了一下BroadcastReceiver的写法,使用的是动态注册的方式,所以和上述这条规则又不相符。

那么是不是这项规则在什么系统版本下又延展到动态注册上面了呢?我没有查阅到任何相关的资料。

最后,我尝试把targetSdkVersion设置成33,发现即使不指定App包名,广播消息也能收到。只要设置成了34,不指定App包名广播就会丢失,且没有任何错误出现。所以这个问题一定是和Android 14的新特性有关了。

我翻遍了Android 14全部的行为变更,只有限制隐式Intent这项能够勉强匹配得上,但BroadcastReceiver不同于Activity和Service的行为又让我感觉无法解释。

百思不得其解的我只好开始尝试把锅往Google身上甩了,我在想着要么这就是Android 14系统中的一个bug,要么就是Android官方文档没写清楚,把BroadcastReceiver这种特殊情况漏写了。

我跟guting说,我再花点时间研究一下,要是实在整不明白我就去给Google提bug。

结果这一研究,还真让我发现了真实的问题所在。

现在我们已经知道,App target到Android 14之后,隐式Intent启动内部Activity和Serivce是会崩溃的。

但是这个崩溃的日志是什么,我却从来没有仔细观察过。

我本来以为应该是什么Security Exception之类的错误,提醒我们当前的代码是有安全问题的。

结果并不是,崩溃的原因是ActivityNotFoundException: No Activity found to handle Intent。

我以为发现了Android 14系统中的一个bug,然而...,Android疑难解析,android,bug,kotlin,jetpack

这个崩溃原因让我豁然开朗。

所以这里并不是因为代码的写法不够安全从而系统抛出了一个安全异常,而是纯粹地系统找不到一个Activity能够处理我们发起的这个Intent。

那么这里考一下大家Android这三大组件在无法处理发起Intent的情况下,各自的行为是什么?

如果没有任何一个Activity能够处理Intent启动Activity的请求,App会崩溃。

如果没有任何一个Service能够处理Intent启动Service的请求,App会崩溃。

如果没有任何一个BroadcastReceiver能够接收到Intent发送出来的广播,什么都不会发生。

想想这是不是我们所熟知的三大组件原有的默认行为,长期以来一直都是如此,只是这个问题套了个Android 14的壳子,让我一度迷失在了Android各系统版本行为变更的细节里面,以至于没能快速找出问题的本质。

所以现在我也不着急去给Google提bug了,我又再次仔细阅读了一下Android官方文档上面的说明:

我以为发现了Android 14系统中的一个bug,然而...,Android疑难解析,android,bug,kotlin,jetpack

重点都在第一句话上了,隐式Intent只会发送给外部组件,内部组件压根无法接收到隐式Intent。那么对应到Activity、Service和BroadcastReceiver上的行为当然就是崩溃、崩溃和丢失了。

最终证明,Android官方文档的严谨性确实是滴水不漏,还是我自己太稚嫩了。

最后讲一个小插曲。

前段时间去上海参加Devfest的时候碰到了Google的AI技术推广工程师魏巍老师,最近一年全球范围内AI实在是太火了,而魏老师也是这个领域的专家。

吃饭时候跟魏老师闲聊,他提到自己在Google之前也是做过Android的,后来又转去做了AI。

魏老师跟我开玩笑说,自己做Android的时候觉得Android实在是太难了,各个系统版本的变化新特性什么的绕来绕去,根本记不住,所以才去做了AI,说AI比较简单。我听后笑了笑。

今天我再次苦笑一声。


如果想要学习Kotlin和最新的Android知识,可以参考我的新书 《第一行代码 第3版》,点击此处查看详情。文章来源地址https://www.toymoban.com/news/detail-782963.html

到了这里,关于我以为发现了Android 14系统中的一个bug,然而...的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 魅族X8解BL锁刷MIUI12.5完美系统暂时没有发现bug,其他手机也可以参考

    1.第一步首先准备的东西有: 1.1adb工具包(包含twrp) adb工具包用来在fastboot mode(线刷)模式中解锁bootloader。这里我会提供(https://wwse.lanzouj.com/b02ea7x0h     密码:YYNB) 现在流行twrp来刷机,所以这个是必须的。 1.2刷机包 这里我提供了很多刷机包不过这里我只说miui怎么完美

    2024年02月03日
    浏览(163)
  • android中的app打成apk发现不能安装是什么原因呢?

    1、生成未签名的安装包 Build - Build Bundle(s)/APK(s) - Build APK(s)    会生成一个未签名的apk文件,默认为debug版,可以正常安装使用。 可以 Build - Select Build Variant - 选择生成的apk版本(debug、release),再 Build - Build Bundle(s)/APK(s) - Build APK(s) 生成对应版本的apk文件。 注意:release版本

    2024年02月16日
    浏览(39)
  • Linux下发现一个高安全性的系统管理工具

      软件 AnySetup 主要功能 主要功能是对Linux操作系统下的基本配置进行管理、多种服务配置进行管理、安全配置进行管理等。如:操作系统的升级管理,软件包的安装、更新和卸载管理,软件仓库源的管理,系统时间和时区的管理,系统语言环境的管理,网络环境的配置管理,

    2024年02月13日
    浏览(44)
  • 在数据库造数据发现的bug也是bug

           上个月,我和开发小哥讨论过一个问题,开发小哥专门提醒我,页面上新增功能尽可能在前端造一些数据去测试,如果直接从数据库里插入的数据,定位问题还是有些说不清楚。 讨论的过程和细节就是以下的对话内容: 测试小姐姐: 企业设备翻页查询的时候报这个错

    2024年02月02日
    浏览(48)
  • Android底层摸索改BUG(二):Android系统移除预置APP

    Android 系统如何预装第三方应用以及常见问题汇集 android Android.mk属性说明及预置系统app操作说明系 Android 中去除系统原生apk的方法 其实就是上面的链接3,但是这个方法有局限性,比较适用于单个Android系统项目,直接对Android.mk中的相关APK代码进行删除,(下图来源链接3) 但

    2024年02月07日
    浏览(54)
  • 奇妙的探索——偶然发现的bug

    今天想在腾讯招聘官网找几个前端的岗位投一下,最近自己也在找工作,结果简历还没有投出去,就发现了腾旭招聘官网的3个前端bug。 1.有时候鼠标hover还没有滑倒下拉选框的菜单上,就消失了,消失的太快了,根本点不到(偶发bug) 2.界面提示我绑定已有账号,接口报错,

    2024年04月25日
    浏览(29)
  • 线上生产环境发现Bug怎么办?

    当在线上生产环境发现Bug时,以下是一些应该采取的步骤: 1.确认和复现Bug 确认Bug的存在,并尽可能复现Bug的步骤和条件。这有助于更好地理解Bug的根本原因,并有助于后续的修复工作。 2.记录Bug信息 记录Bug的详细信息,包括Bug的描述、复现步骤、影响范围、操作系统和浏

    2024年02月16日
    浏览(38)
  • 【SpringCloud】深入探究Eureka:构建微服务架构中的高效服务发现系统

    👨‍💻博主主页:小尘要自信 在现代的软件开发中,微服务架构已经成为了一个热门的话题。微服务架构的一个关键组成部分就是服务发现。而在服务发现领域,Eureka无疑是一个备受推崇的解决方案。本篇博客将为您介绍什么是Eureka以及如何在您的微服务架构中应用它。

    2024年02月14日
    浏览(41)
  • Spring Boot如何实现分布式系统中的服务发现和注册?

    随着互联网的快速发展,越来越多的企业开始将自己的业务迁移到分布式系统中。在这种情况下,服务发现和注册变得尤为重要。对于分布式系统中的每个服务来说,它需要知道其他服务的位置和状态,这样才能进行通信和协作。Spring Boot提供了一些工具和框架,可以帮助我

    2024年02月07日
    浏览(39)
  • 同事写了个惊天 bug,还不容易被发现。。

    作者:树洞君 链接:https://juejin.cn/post/7064376361334358046 从6点32分开始少量用户访问app时会出现首页访问异常,到7点20分首页服务大规模不可用,7点36分问题解决。 6:58 发现报警,同时发现群里反馈首页出现网络繁忙,考虑到 前几日 晚上门店列表服务上线发布过,所以考虑回滚

    2024年02月14日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包