在 Android 框架中,接口的可见性规则

!!!出现问题:当普通应用通过SDK调用接口时遇见AndroidRuntime: java.lang.NoSuchMethodError: No virtual method

得知:Android 中接口访问控制规则说明

在 Android 系统开发中,不同包名下的接口默认访问权限是不一样的。以下是详细的说明。

1. frameworks/base/core/java/android.* 包下新增的接口

  • 默认访问权限:公开(public)
  • 是否可被普通应用直接访问:✅ 是
  • 说明
    • 这些接口属于系统公开 API。
    • 普通应用可以直接调用这些类和方法。
    • 系统应用可以直接调用这些类和方法。

示例:

java 复制代码
package android.app;

public class MyManager {
    public void doSomething() { ... }
}

该方法 doSomething() 可以被任意普通 App 调用。


2. 其他包下新增的接口(如 frameworks/base/core/java/com/android/server, frameworks/base/core/java/com/android/internal,只要不是 frameworks/base/core/java/android.*都是默认隐藏的接口)

  • 默认访问权限:隐藏(hidden)
  • 是否可被普通应用直接访问:❌ 否
  • 是否可被系统应用直接访问:✅ 是
  • 说明
    • Android 从 10 开始加强了对隐藏 API 的限制(Hidden API Policy)。
    • 即使你在 SDK 中能看到这些类或方法,运行时也会被限制访问。
    • 只有系统应用能正常访问

3. 如何开放隐藏接口给普通应用?

使用注解:

java 复制代码
@UnsupportedAppUsage

作用:

  • 标记该方法为"被系统使用",并允许通过反射等方式被普通应用访问。
  • 在构建时,该注解会保留到 public-api.xmlsystem-api.xml 中,避免被标记为 hidden。

示例:

java 复制代码
package com.android.server.myfeature;

import android.annotation.UnsupportedAppUsage;

public class MyInternalService {

    @UnsupportedAppUsage
    public void exposeToApp() {
        // 可以被普通 App 调用
    }
}

添加此注解后,普通应用可以通过以下方式调用:

  • 反射调用;
  • 在调试模式下(开启 --runtime-flags allow-incompatible-changes)直接调用。

⚠️ 注意事项

项目 说明
注解用途 用于兼容性过渡,不建议长期依赖
兼容性风险 使用隐藏 API 有版本升级不兼容的风险
官方推荐 如果需要开放接口,应申请加入 SDK Public API
Android 版本限制 Android 10 及以上加强了 hidden API 控制,需特别注意

🧩 延伸建议

如果你是在系统框架层修改代码,并希望某个接口能被第三方 App 调用,请确保:

  1. 接口所在的类/包不是 @hide
  2. 方法上加上 @UnsupportedAppUsage
  3. 构建时确认其出现在 public-api.xml 中;
  4. App 编译时能找到对应的类和方法(可通过反射或定制 framework.jar)。

相关推荐
阿巴斯甜13 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker13 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952714 小时前
Andorid Google 登录接入文档
android
黄林晴15 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android