You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio项目Java 11环境下配置bootstrapClasspath无法访问framework.jar隐藏API的问题求助

Android Studio项目Java 11环境下配置bootstrapClasspath无法访问framework.jar隐藏API的问题求助

嘿,我来帮你捋清楚这个问题的根源,再给出针对性的解决方案:

问题根源分析

这个问题主要和两个核心变化直接相关:

  1. Java版本的模块系统差异
    Java 9引入了JPMS(Java平台模块系统),Java 11是完全支持该系统的稳定版本。在Java 8及以前,JVM会直接加载bootstrapClasspath中的所有类,不管API是否被标记为隐藏;但Java 11+会严格遵循模块系统的规则,只有模块中显式导出的包才能被外部代码访问,而framework.jar里像TypedArray.getThemeAttributeId这类隐藏API所在的包(比如android.content.res)默认是未导出的,所以哪怕你把framework.jar加入了bootstrapClasspath,也无法正常访问。

  2. Kotlin插件的适配逻辑变化
    Kotlin 2.2.0插件对Java 11+的模块系统做了完全严格的适配,100%遵循JPMS的访问规则;而2.0.0版本还没有强制执行这些规则,相当于“绕过”了模块系统的限制,所以旧版本能正常访问隐藏API,新版本就触发了合规检查导致失败。

解决方案

方案一:给Java编译任务添加模块导出参数

修改你build.gradle.kts中的JavaCompile任务配置,显式允许访问目标API所在的未导出包:

gradle.projectsEvaluated {
    tasks.withType<JavaCompile> {
        val newFiles = mutableListOf<File>().apply {
            add(File("libs/framework.jar"))
            options.bootstrapClasspath?.let { addAll(it.files) }
        }
        options.bootstrapClasspath = files(newFiles)
        // 根据你要访问的API所在包调整,这里以android.content.res为例
        options.compilerArgs.add("--add-exports=android.content.res/android.content.res=ALL-UNNAMED")
        // 如果需要访问多个包的隐藏API,添加多个--add-exports参数,比如:
        // options.compilerArgs.add("--add-exports=android.view/android.view=ALL-UNNAMED")
    }
}

方案二:同步配置Kotlin编译任务

因为你的项目用了Kotlin,只配置JavaCompile是不够的,还需要给Kotlin编译任务添加相同的参数:

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions {
        jvmTarget = "11"
        // 对应Java编译的--add-exports参数,包路径要和上面保持一致
        freeCompilerArgs += "--add-exports=android.content.res/android.content.res=ALL-UNNAMED"
    }
}

方案三:全局JVM参数配置(谨慎使用)

如果上面的配置还是不生效,可以尝试在gradle.properties中添加全局JVM参数,强制允许访问目标包:

org.gradle.jvmargs=--add-exports=android.content.res/android.content.res=ALL-UNNAMED

注意这个是全局配置,可能会影响项目中的其他模块,所以优先用前两个方案。

补充说明

为什么Java 8和旧Kotlin插件能正常工作?

  • Java 8没有模块系统,JVM不会检查包的导出状态,只要framework.jar在bootstrapClasspath里,就能直接访问里面的所有API,包括隐藏的。
  • Kotlin 2.0.0插件对Java 11的模块系统适配不够严格,没有强制执行JPMS的访问规则,所以即使没有显式声明导出,也能“偷偷”访问隐藏API;而2.2.0插件完全遵循了模块系统的规范,所以必须显式声明要访问的未导出包。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 11:25:26