Android P 应用兼容常见错误及建议

从 2018 年 3 月初我们发布 Android P 开发者预览版以来,很多开发者都对当前常见应用在 Android P 上做了一些兼容性测试,我们在这里总结了一些常见的问题,以及它们发生的原因和建议的修改措施。

问题 1: 假设 android.os.Build.VERSION.RELEASE 为数值类型

原因:

对于即将推出的 Android 新版本的预览版,这些值可能是字母数字 (如 “PPR” 或 “P”),因此在尝试将 “P” 解析为整数时会导致崩溃。

建议:

应用把 RELEASE 的值作为字符串类型来处理。

问题 2: 使用的第三方 SDK 版本过低,不兼容 Android P

原因:

在中国的 Android 生态中,应用经常依赖的第三方 SDK (特别是加固和热修复框架) 会和系统底层紧密集成 (如使用非公开的接口),而导致应用在 Android 版本升级时无法正常运行。我们也开始与一些常见的 SDK 提供商合作 (并计划覆盖更多),在 Android 新的预览版本中尽早解决兼容性问题。

建议:

经常检查第三方 SDK 的升级公告,及时升级至其最新版本。

如果您使用的第三方 SDK 尚不支持 Android 新版本,请报告给其提供商,帮助推动它解决兼容性问题。

问题 3: 开启应用时显示 "Detected problems with API compatibility",或调用非 SDK 接口时遭遇 NoSuchFieldException 或 NoSuchMethodException

原因:

非 SDK 接口指的是 Android 系统内部使用、并未提供在 SDK 中的接口,开发者可能通过 Java 反射、JNI 等技术来调用这些接口。但是,这么做是很危险的:非 SDK 接口没有任何公开文档,必须查看源代码才能理解其行为逻辑。

非 SDK 接口的函数签名 (包括参数列表和返回值)、行为逻辑都有可能在下个 Android 版本中被大幅修改,甚至 API 本身也可能被删除。这会导致使用非 SDK 接口的应用在新的 Android 版本中无法运行,或运行时产生不符合预期的行为,开发者必须投入相当的研发资源保持其在未来每个 Android 新版本中的适配。

直接使用底层的非 SDK 接口有可能会绕过一些 Android 对用户的安全性和隐私性方面的保护,不但影响用户体验、妨害用户隐私,也很可能会被 Google Play Protect 判定为恶意软件而提示用户卸载应用。

从 Android P 开始,系统会限制非 SDK 接口的使用

建议:

只使用 Android SDK 中的公开接口进行应用开发。公开 SDK 接口有详细的技术文档和支持渠道,未来的 Android 新版本也会保证公开 SDK 接口的兼容性 (即使有改动,也会在文档中详细阐明)。

请尽早在 Android P 预览版中测试您的应用,您可以运行并操作应用,然后在 adb logcat 中查找类似下方的内容,其中包含了应用调用的非 SDK 接口名,所属黑/灰名单和调用的方式: Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI) Accessing hidden method Landroid/app/ActivityThread;->currentActivityThread()Landroid/app/ActivityThread; (dark greylist, reflection)

如果您有合理的理由,必须使用某个非 SDK 接口,请在文章下方留言给我们,我们非常期待聆听和与您进行讨论,并会在充分评估必要性和可行性后,提供可能的方案来满足合理的功能需求。

问题 4: 直接调用 dex2oat,或者使用不支持 / 不正确的方式编译 dex 文件

原因:

从一开始,dex2oat 就被设计为系统内部使用的编译部署工具,Android 从来都未支持过开发者直接调用 dex2oat 的场景。我们会持续而不定期地对这个工具进行优化,而很多时候其行为变更 (如: 生成的文件及其格式) 都是与之前不兼容的。在大多数情况下,标准的类加载器 (BaseDexClassLoader / DexClassLoader / PathClassLoader) 无法找到或使用由直接调用 dex2oat 生成的文件。

此外请注意,从 Android O 开始,BaseDexClassLoader 和 DexClassLoader 构造函数中的 “optimizedDirectory” 参数已废弃,并在加载 dex 文件时不起作用。

建议:

如果您需要从内存中加载 dex 文件,而不愿在存储中留下痕迹,请使用 Android O 中新增的加载器 InMemoryDexClassLoader。

问题 5: 注入或篡改 Android Studio 生成的 dex 和 so 文件

原因:

Android Studio 生成的 dex 文件虽然有公开的布局格式,但具体内容还是会在运行时被系统在后台进行编译优化。如果您在 dex 文件中写入自定义的内容,很可能这些自定义的写入操作与系统优化发生冲突,以致自定义的内容被擦除或覆盖,甚至导致优化后的 dex 在执行时直接崩溃。

Android Studio 生成的 so 文件包含一些元数据 (如 ELF headers 和 section headers),以备动态链接器进行完整性检查。篡改 so 文件并不会带来安全性的提升 (很多工具可以重新生成元数据),反而可能导致应用无法在未来的 Android 版本中启动 (由于动态链接器可能执行更严格的检查)。更多关于 so 文件的要求,您可在公众号平台发送信息 “so文件” 获取相关链接。

建议:

不要修改 Android Studio 生成的 dex 和 so 文件。

问题 6: 应用在 Android P 上启动时显示 “This app was built for an older version of Android and may not work properly...”

原因:

应用的 targetSdkVersion 太旧 ( <17 )

建议:

升级您应用的 targetSdkVersion 至最新版本,您可在公众号平台发送信息 “targetsdkversion” 获取相关文档链接。

问题7: 应用在特长屏幕上未能正确显示,部分内容超出屏幕

原因:

Android O 开始支持特长屏幕,而且已经有很多厂商开始发布特长屏幕的手机。应用对屏幕的显示比例做出错误的假设,而未能支持 16:9 以上的纵横比,进而影响用户体验。

建议:

修改您的应用,使他能够适应不同的屏幕尺寸 (包括 16:9 以上的纵横比)。

如果自适应式 UI 不适合您的场景,可以考虑在 manifest 中的 内设置 resizableActivity = false,并加上 android:MaxAspectRatio 来声明最大支持纵横比。这会在特长屏幕的设备上启用兼容模式,把应用边缘的显示空间以黑色填充。

问题 8: 应用在特长屏幕上未能正确显示,上下出现黑边

原因:

Android O 开始支持特长屏幕,而且已经有很多厂商开始发布特长屏幕的手机。应用对未能支持 16:9 以上的纵横比会在特长屏幕的设备上启用兼容模式,把应用边缘的显示空间以黑色填充。

建议:

升级您应用的 targetSdkVersion 至最新版本,您可在公众号平台发送信息 “targetsdkversion” 获取相关文档链接。

请参考下列 Android P 相关文档,使您的应用尽早兼容 Android P:

设置 SDK 和模拟器

迁移指南

行为变更

新功能及 API

如果您在 Android P 的兼容性工作中有什么经验和体会,欢迎在文章下方留言与我们分享。谢谢!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

每个极客都应该知道的Linux技巧

检查不是由你运行的程序 难度:高级 应用程序:bash(译注:UNIX或者LINUX的shell) 想象下这个场景-你已经准备好了要和同事在办公室里对战一局快速...

309100
来自专栏信安之路

线下赛ASP靶机漏洞利用分析

继上次发表 记一次线下赛靶机攻击过程 后,看到反响不错,特此再写一篇,关于一台 ASP 靶机漏洞利用过程。

50700
来自专栏FreeBuf

OpenSSH曝高危漏洞,Linux主机面临暴力破解威胁

OpenSSH软件被爆出一个简单却高危的漏洞,攻击者可以在短时间内进行数千次的登录尝试。 ? OpenSSH是最流行的Linux系统进行远程控制的软件。一般来说...

30970
来自专栏FreeBuf

手机没Root?你照样可以渗透路由器

和Metasploit差不多,RouterSploit是一个强大的漏洞利用框架,用于快速识别和利用路由器中的普通漏洞,它还有个亮点,就是可以在绝大多数安卓设备上...

55640
来自专栏杨建荣的学习笔记

强大的awr format (r4笔记第14天)

awr报告对于dba而言是工作中重要的一部分内容,有些时候感觉跟去医院看病的化验单一样,各种指标和参数。有些高了,有些低了都是需要注意的内容。之前打印了一份aw...

28240
来自专栏疯狂的小程序

ASP获取微信小程序的OpenID服务器端代码

尝试一下新鲜事物“微信小程序”,其中有一个业务场景,通过微信登陆小程序,这样需要获取小程序的用户ID(也就是openid)。微信小程序从安全角度考虑,不提供直接...

82380
来自专栏大魏分享(微信公众号:david-share)

一个虚拟化客户上云的需求分析&架构设计-大卫的Azure学习笔记大全

案例分析与架构设计 案例分析:大卫公司电子商务网站案例研究 大卫公司是北京的一家媒体和出版公司,拥有约2000名员工。它有一个成功的直接面向消费者的电子商务网站...

42480
来自专栏coding

django2.0入门教程第一节启动开发模式下的服务器

17220
来自专栏Seebug漏洞平台

GPON Home Gateway 远程命令执行漏洞分析

2018/04/30,vpnMentor公布了 GPON 路由器的高危漏洞:验证绕过漏洞(CVE-2018-10561)和命令注入漏洞(CVE-2018-1...

11410
来自专栏飞雪无情的博客

使用AlarmManager设置的定时服务在Android4.4上可能不准确了

Android4.4在前天发布了,随着Android4.4的源代码的放出,相信会有更多的手机会慢慢的升级到Android4.4,作为苦逼的Android开发人员...

10130

扫码关注云+社区

领取腾讯云代金券