Android 9.0(Android P)如何限制应用调用内部 API

242 阅读2分钟

这篇文章主要讲了 Android 9.0(Android P)如何限制应用调用内部 API(非 SDK 接口),以及背后的技术原理和影响,用通俗的话总结如下:

一、为什么限制内部 API?

  • 兼容性问题:很多 App 偷偷使用 Android 系统未公开的内部 API(标 @hide 的方法 / 字段),但这些接口没被官方支持,Android 大版本升级时可能突然删除或修改,导致 App 崩溃(比如 Android P 升级后大量 App 闪退)。
  • Google 的目标:强制 App 使用官方 SDK 接口,让 Android 生态更稳定,避免 “黑科技” 破坏兼容性。

二、限制后的表现:用内部 API 会报错

如果 App 通过反射(如getDeclaredMethod)或 JNI 调用内部 API,会出现以下错误:

  • 反射调用:抛出NoSuchMethodException/NoSuchFieldException
  • JNI 调用:返回 NULL,引发崩溃;
  • 甚至会弹出 Toast 警告(调试模式下)。

三、限制机制:像 “门禁系统” 一样检查 API 访问

当 App 调用内部 API 时,系统会按以下流程 “安检”:

  1. 反射 / JNI 调用触发检查
    比如调用Class.getDeclaredMethod()时,最终会走到 native 方法getDeclaredMethodInternal,然后进入检查逻辑ShouldBlockAccessToMember

  2. 检查是否 “允许进入”(白名单 / 策略判断)

    • 白名单(kWhitelist) :允许访问,比如系统核心 API;
    • 灰名单(Light/Dark Greylist) :根据 “策略严格程度” 决定是否警告或禁止;
    • 黑名单(kBlacklist) :直接禁止访问。
  3. 策略严格程度(EnforcementPolicy)

    • kNoChecks:不检查,全允许(测试用);
    • kJustWarn:只警告,不禁止;
    • kDarkGreyAndBlackList:禁止深灰名单和黑名单;
    • kBlacklistOnly:只禁止黑名单(Android P 默认策略)。
  4. 豁免情况(类似 “VIP 通行证”)

    • 系统 App(用平台密钥签名)、BootClassLoader 加载的类、调试模式下标记为可信任的类,可绕过限制。

四、黑白名单怎么来的?

  • 编译时确定:系统编译时,会根据hiddenapi-force-blacklist.txt等文件,将 API 分类到不同名单,记录在 dex 文件的访问标志中。
  • 厂商限制:手机厂商可以往黑名单加自己的 API,但不能删除 Google 的名单,保证兼容性。

五、对开发者的影响和建议

  1. 不能再用 “黑科技”
    比如插件化、热修复等依赖内部 API 的技术会受影响,需改用官方接口。

  2. 如何检测?

    • 用 AOSP 的veridex工具扫描 App 是否使用内部 API;
    • 运行时会打印警告日志(如Accessing hidden method...)。
  3. 绕过限制的方法(不推荐)

    • 修改系统策略(如设置EnforcementPolicy为不检查);
    • 将类加载器换成 BootClassLoader;
    • 添加豁免名单(但 Google 在封堵这些漏洞)。

六、总结

Android P 的内部 API 限制就像给系统加了 “门禁”,强制 App 用官方接口,虽然短期内让插件化等技术变难,但长期看能让 Android 生态更稳定。开发者需避免使用非 SDK 接口,否则升级系统时可能遇到兼容性问题。