非 SDK 接口常见问题 | Android 开发者 FAQ Vol.13

常规问题 Q1:

什么是非 SDK 接口?

A:非 SDK 接口指不在官方 Android SDK 涵盖范围内的 Java 字段和方法。此类接口是 SDK 的内部实现细节,可能随时会被修改,且不对开发者另行通知。

常规问题 Q2 :

Android P 在非 SDK 接口使用限制方面采取了哪些举措?

A:谷歌正在逐步限制非 SDK 接口的使用:针对不同接口采取不同形式的限制 (详情请参照条目 “应用运行时,我应该如何检测非 SDK 接口的使用?” )。若您正在使用非 SDK 接口进行开发,请特别注意限制对应用行为造成的影响。

常规问题 Q3:

如果我正在使用非 SDK 接口,我应该如何提交请求,申请重新评估该接口?

A:请提交申请并提供需要使用此接口的详细原因。

常规问题 Q4:

非 SDK 接口都有哪些不同管控名单?且不同名单下接口的限制又有何不同?

A:以下为各名单的具体说明:

  • 白名单:SDK 本身
  • 浅灰名单:仍允许调用的非 SDK 方法和字段
  • 深灰名单
    • 若应用的 target SDK 低于 Android P (即 targetSdkVersion <28):允许调用深灰名单中的接
    • 若应用的 target SDK 为 Android P 或更高 (即 targetSdkVersion >= 28):深灰名单与黑名单的限制相同
  • 黑名单:不论 target SDK 版本为多少,所有应用均不允许调用黑名单接口。对开发者来说,相当于系统里不存在这些接口。比如,当应用试图调用此类接口时,系统会抛出 NoSuchMethodError / NoSuchFieldException 异常,并且在应用获取特定类的字段和方法列表时,不在返回列表中包含此类接口。

常规问题 Q5:

我在应用开发过程中引用了不少第三方库,很难发现它们调用了哪些私有 API,请问谷歌能否提供编译时工具帮助我追踪这些违规行为?

A:您可尝试 AOSP 开源项目中的静态分析工具 “veridex” 及其预编译可执行程序

常规问题 Q6:

应用运行时,我应该如何检测非 SDK 接口的使用?

A:这取决于您针对哪个版本的 Android P (开发者预览版或 Beta 测试版) 进行应用开发。所有违规调用情况都会收到 logcat 警告信息:“Accessing hidden field|method …”。此外:

  • 在开发者预览版 1 以及 Beta 2 中,当应用试图调用深灰名单中的非 SDK 接口时,系统会在 Activity 启动时弹出 Toast 警告信息 “Detected problems with API compatibility” 。
  • 从 Beta 1 开始,开发者可以使用 StrictMode 中的 permitNonSdkApiUsage() 以及 detectNonSdkApiUsage() 方法,在非 SDK 接口被调用时会收到回调,如添加一条日志。
  • 在 Andrid P 最终版本中:Toast 信息只在调试版本的应用中显示;同时仅在非 SDK 接口调用被拒绝的情况下,系统才会打印 logcat 信息。

常规问题 Q7:

谷歌如何确保通过问题跟踪器了解所有应用需求?

A:起初,我们基于对应用的静态分析列出名单,并辅以下列方式予以完善:

  • 手动测试对 Play 商店内外的顶级应用;
  • 内部报告;
  • 从内部用户自动收集数据;
  • 开发者预览报告;
  • 进行额外静态分析,在分析中适当增加误报 (false positive) 信息。

常规问题 Q8:

我应该如何允许访问非 SDK API?

A:可以通过使用 adb,在开发设备上允许访问非 SDK API。

若您想在 adb logcat 中显示 API 访问信息,您可通过以下命令更改 API 执行策略:

  • adb shell settings put global hidden_api_policy_pre_p_apps 1
  • adb shell settings put global hidden_api_policy_p_apps 1

更改回默认设置:

  • adb shell settings delete global hidden_api_policy_pre_p_apps
  • adb shell settings delete global hidden_api_policy_p_apps

以上命令不需要设备获得 Root 权限。

命令最后的数字分别表示:

API 名单相关问题 Q1:

在开发者预览版和 beta 版中,各名单处于何种状态?

A:在 Android P 开发过程中,我们对各名单进行了不同方式的迭代:

  • 开发者预览版 1:仅有浅灰和深灰名单。所有我们试图限制的非 SDK 接口都被列在深灰名单中。
  • Beta 1:仅有浅灰名单和黑名单。在预览版1的基础上对浅灰名单进行增补,其余非 SDK 接口均移至黑名单。
  • Beta 2:浅灰、深灰和黑名单均存在,许多黑名单中的接口被移至深灰名单。

请注意:Beta 2 与最终版 Android P 对非 SDK 接口使用限制基本一致。

API 名单相关问题 Q2:

Android P 中的深灰名单包含哪些内容?

A:深灰名单中包含了在开发阶段中未被发现使用的方法和字段,但我们有可能会有疏漏,所以我们也将一些与公开 SDK 及浅灰名单中的接口密切相关的接口也移入了深灰名单。

API 名单相关问题 Q3:

我应该去哪里查阅灰名单和黑名单?

A:它们都被编译进 Android 平台中。您可前往以下地址查找编译前的条目:

  • platform/prebuilts/runtime/appcompat/hiddenapi-light-greylist.txt: AOSP 源代码中的浅灰名单接口 (名单 1)
  • platform/prebuilts/runtime/appcompat/hiddenapi-dark-greylist.txt: AOSP 源代码中的深灰名单接口 (名单 2)

此外,您可前往该地址查看 SDK 28 中的浅灰名单接口 (名单 3)。

黑名单与深灰名单是在平台编译时按照一定规则自动生成的。我们也添加了一条编译规则在 AOSP 开源项目中生成这些名单。请注意:这里生成的黑名单与 Android P 中的黑名单不相同,但差别不大。开发者可下载 AOSP 开源项目,然后通过以下命令生成黑名单:make hiddenapi-aosp-blacklist

生成文件的路径为:out/target/common/obj/PACKAGING/hiddenapi-aosp-blacklist.txt

API 名单相关问题 Q4:

每个名单中约多少条目?

A:在 Beta 2 版本中:

  • 白名单 (即 SDK 本身):约 74,000 个方法和字段;
  • 浅灰名单:约 11,000 个方法和字段;
  • 深灰名单:约 121,000 个方法和字段;
  • 黑名单:约 9,000 个方法和字段。

API 名单相关问题 Q5:

如何在开发者预览版系统映像文件中找到黑名单和灰名单?

A:这些名单被编码在平台 dex 文件中的字段和方法的访问标志中。系统映像中没有包含这些名单的单独文件。

API 名单相关问题 Q6:

搭载同一版本的不同设备是否共同一套黑名单 (或灰名单)?

A:是的。OEM 厂商可以在黑名单中添加自己的 API,但是不允许从原始 / AOSP 黑名单 (或灰名单) 中移除项目。兼容性标准文档 (CDD) 禁止此类更改,且兼容性测试 (CES) 会确保 Android 运行时 (ART) 检查该名单。

API 名单相关问题 Q7:

在非 SDK 接口限制方面,开发者预览版和最终版本的行为是否相同?

A:仅开发者预览版会显示 Toast 信息,最终版本将不再显示此类信息。此外:

  • 开发者预览版 1 无黑名单,仅有浅灰和深灰名单警告;
  • Beta 1 将所有深灰名单条目移至黑名单;
  • Beta 2 将大部分黑名单中的接口移至深灰名单。Beta 2 的限制名单和最终版应该十分接近,不过依旧会根据收到的反馈进行一定修改。

相关应用兼容性问题 Q1:

原生代码中是否存在非 NDK 接口的限制?

A:SDK 针对 Java 语言。关于针对 C 或 C++ 代码的 NDK,我们已经在 Android Nougat 中做出了限制: Android N 限制使用私有 C/C++ 符号, 提升系统稳定性

相关应用兼容性问题 Q2:

谷歌是否计划限制 dex2oat 或 dex 文件操作?

A:我们暂时不会限制开发者访问 dex2oat 二进制文件,但是在开发文档《Dalvik 可执行文件格式》指定的 dex 公开格式以外,我们不保证其它 dex 文件格式及其接口的稳定性。我们保留随时更改或移除 dex2oat 文件和未指定格式的 dex 文件的权利。请注意,通过 dex2oat 转换的文件格式,如 odex (即 oat)、vdex、cdex 等,均为未指定格式。

相关应用兼容性问题 Q3:

如果关键第三方 SDK(尤其是,加固工具)必须调用非 SDK 接口,而第三方开发者也承诺该接口会兼容未来 Android 版本,Android 能否取消对该接口的警告?

A:我们不会因为单独 SDK 用例就放宽兼容性要求。如果 SDK 合作伙伴无法保证兼容现行的白名单和灰名单接口,他们可以提交需求,申请使用某个非 SDK 接口。

在 Android P 中,我们暂时不会对 Android 应用或 SDK 当前已使用的非 SDK 接口加以限制,但在今后,若相关接口有合适的 SDK 替代选项,我们计划引入 target SDK 限制。注意:如果调用了非 SDK 或非 NDK 接口,这些接口中的大部分每年都会出现兼容问题,需要不断进行适配。

相关应用兼容性问题 Q4:

非 SDK 接口限制是否适用于所有应用 (包括系统应用和第一方应用),而不仅仅是第三方应用?

A:是的。但是由平台密钥签名的应用不受限制,同时我们还为一些系统映像中的应用提供了软件包级别的白名单。请注意:此类豁免仅适用于系统映像中的应用(或更新后在系统映像中的应用)。

该名单仅限于使用平台中的私有接口进行开发的应用,而非调用 SDK 中的私有接口 (即 LOCAL_PRIVATE_PLATFORM_APIS := true) 的应用。

相关应用兼容性问题 Q5:

某些开发者已经发表文章,公布了私有 API 限制的运行机制以及突破方法,谷歌方面对此有何看法?是否会加强管控?

A:我们知道会有潜在的方法来帮助开发者绕过限制。不过,好在大部分应用坚持使用公开 API。我们会加大调用非 SDK 接口的难度,确保应用兼容性,与此同时找到一个比较好的平衡点,方便运行时的调试。我们将继续开展具体实现的评估工作,与开发者保持积极合作。

如果您仍然有关于系统及兼容性等问题,欢迎给我们留言,我们会继续收集有代表性的问题,请我们的工程师做出解答,并将答案尽量及时地回复给大家。同时,也请关注下一期的 “Android 开发者 FAQ” 专题文章,希望可以帮助您补充相关知识技能。

点击查看《对于非 SDK 接口的限制》文档了解详细信息.

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

一个简单的node爬虫踩坑之路

一个简单的node爬虫踩坑之路准备工作 最近在看爬虫相关的文章,偶然想起来尝试一下用node来实现一个简单的爬虫。但是爬别的多没意思,当然是爬美女图片啊。。。 ...

1969
来自专栏程序员的碎碎念

如何解决Python包依赖问题

以简洁高效(指编程较为高效, 而不是运行速度)出名的Python, 在包依赖问题上有时候让人挠头.

972
来自专栏Java架构

今咱们来聊聊JVM 堆外内存泄露的BUG是如何查找的

JVM的堆外内存泄露的定位一直是个比较棘手的问题。此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤了Bug的源头。笔...

77417
来自专栏互联网高可用架构

通用架构师应该如何把控迁移技术方案

2186
来自专栏张戈的专栏

解决Nginx配置http2不生效,谷歌浏览器仍然采用http1.1协议问题

昨天一个网友通过 QQ 联系我,说按照我博客之前分享的 http2 配置教程不能生效,想请我帮忙看看。 经过测试,使用谷歌浏览器访问他的测试站点,确实没有开启 ...

3597
来自专栏木可大大

漫谈文件系统

翻译成中文大致意思:文件系统主要是管理数据存储以及数据如何检索的,而数据存储在磁盘或内存中。上期我们聊过了漫谈虚拟内存,本期我们就重点介绍磁盘中的机械磁盘的组成...

50612
来自专栏云计算教程系列

CentOS 如何配置NTP加入NTP池项目

准确的计时对于几乎所有服务或软件都至关重要。在分布式平台上运行的电子邮件,记录器,事件系统和调度程序,用户身份验证机制和服务都需要准确的时间戳来按时间顺序记录事...

1320
来自专栏Java架构

今咱们来聊聊JVM 堆外内存泄露的BUG是如何查找的前言内存泄露Bug现场查找线索总结

2074
来自专栏解Bug之路

解Bug之路-记一次JVM堆外内存泄露Bug的查找 顶

JVM的堆外内存泄露的定位一直是个比较棘手的问题。此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤了Bug的源头。笔...

824
来自专栏Netkiller

Linux Token Auth 一次性密码认证

Linux Token Auth 一次性密码认证 摘要 服务器端脚本: https://github.com/oscm/devops/blob/master/b...

2953

扫码关注云+社区