1. 背景1.1 Android隐藏API是什么Android 系统中存在大量隐藏 APIHidden API这些 API 被标记为hide意味着它们不在官方 SDK 中公开。简单来说这些接口是系统内部自己用的不是给第三方 App 开发者调用的官方也不会保证你调用后能在不同设备 / 版本上正常工作。1.2 Android 官方为什么要隐藏API稳定性考虑: 隐藏 API 可能在不同 Android 版本之间发生变化Google 不希望第三方应用依赖这些不稳定的接口安全性考虑某些 API 涉及系统底层操作不当使用可能导致安全问题兼容性考虑隐藏 API 的行为可能因设备厂商定制而异内部实现细节某些 API 是 Android 内部实现的一部分不适合外部使用1.3 隐藏 API 的典型使用场景尽管存在风险但在某些特定场景下如系统应用、车载应用、IoT 设备等我们仍然需要调用这些隐藏 API//调用 PowerManager.wakeUp() 唤醒屏幕valpowerManagergetSystemService(POWER_SERVICE)asPowerManagerif(powerManager.isInteractive.not()){powerManager.wakeUp(SystemClock.uptimeMillis(),com.zeekr.flexiscreen.launcher:systemdialog)}//调用 WifiManager.connect() 连接 WiFivalwifiManagergetSystemService(Context.WIFI_SERVICE)asWifiManager wifiManager.connect(WifiConfiguration(),object:WifiManager.ActionListener{overridefunonSuccess(){Log.i(TAG,onSuccess)}overridefunonFailure(reason:Int){Log.i(TAG,onFailure)}})但是直接调用隐藏API会报错 :file:///D:/WorkSpace/Test/FrameApiTest/app/src/main/java/com/example/frameapitest/MainActivity.kt:27:26 Unresolved reference wakeUp.那么需要怎么办呢 ?2. 原本可行的方案原本的Android Studio中存在可行的方案我们先来回顾下 :2.1 步骤一 : 复制framework.jar到app/libs目录下官方给开发者的android.jarSDK 目录下是阉割版—— 移除了hide标记的隐藏 API而framework.jar是包含完整 Android 框架层接口公开 隐藏 API的 jar 包是调用隐藏 API 的核心依赖。有三种方式可以获取到framework.jar从已 Root 的设备 / 模拟器中提取从 Android 源码编译生成使用第三方现成包比如github上有现成已经编译好的framework.jar : aosp-android-jar2.2 步骤二 : 引入 framework.jar使用compileOnly来引入 framework.jardependencies{compileOnly(files(libs/framework.jar))// 其他依赖...}注意这里要用compileOnly而不是implementation否则会报错 :com.android.tools.r8.internal.wx: Absent Code attribute in method that is not native or abstract2.3 步骤三 : 增加gradle配置这一步骤的作用是将你本地的framework.jar包含隐藏 API优先加入到 编译器的引导类路径中让编译器优先使用这个完整的framework.jar而非官方 SDK 中被阉割的android.jar。2.1 方案一在app模块的build.gradle中增加如下配置 :gradle.projectsEvaluated{tasks.withTypeJavaCompile{if(options.bootstrapClasspathnull){options.bootstrapClasspathfiles(libs/framework.jar)}else{valfileSetoptions.bootstrapClasspath!!.filesvalnewFileListmutableListOfFile()newFileList.add(File(libs/framework.jar))newFileList.addAll(fileSet)options.bootstrapClasspathfiles(*newFileList.toTypedArray())}}}2.2 方案二在app模块的build.gradle中增加如下配置 :gradle.projectsEvaluated{tasks.withTypeorg.jetbrains.kotlin.gradle.tasks.KotlinCompile{// 使用新的 compilerOptions DSLcompilerOptions{valframeworkJarfile(libs/framework.jar)// 使用 add 方法添加编译参数freeCompilerArgs.add(-Xbootclasspath/p:${frameworkJar.absolutePath})}}}2.3 方案三在app模块的build.gradle中增加如下配置 :tasks.withTypeorg.jetbrains.kotlin.gradle.tasks.KotlinCompile().configureEach{compilerOptions{valframeworkJarproject.file(libs/framework.jar)freeCompilerArgs.add(-Xbootclasspath/p:${frameworkJar.absolutePath})}}3. 新版Android Studio中失效我使用的是Android Studio Otter 3 Feature Drop | 2025.2.3使用的kotlin版本是2.2.21agp版本是9.0.1在此版本中新建项目依赖framework.jar上述配置会失效。例如在使用方案二的时候会提示 :w:Flagisnot supportedbythisversion of the compiler:-Xbootclasspath/p:D:\WorkSpace\Test\FrameApiTest\app\libs\framework.jar e:file:///D:/WorkSpace/Test/FrameApiTest/app/src/main/java/com/example/frameapitest/MainActivity.kt:27:26 Unresolved reference wakeUp.e:file:///D:/WorkSpace/Test/FrameApiTest/app/src/main/java/com/example/frameapitest/MainActivity.kt:34:21 Unresolved reference connect.原因是由于 Kotlin 编译器在较新版本中已不再支持 -Xbootclasspath/p 参数因此导致了 Flag is not supported 的警告并且因为 framework.jar 未能正确优先加载导致了 Unresolved reference 错误。故需修改 app/build.gradle.kts 配置。移除了不被支持的 -Xbootclasspath/p 参数改为通过调整 KotlinCompile 任务的 libraries classpath顺序来确保 framework.jar 优先于 android.jar 加载从而能够正确访问隐藏 API。4. 新版解决方案还是按照2. 原本可行的方案中的步骤一到步骤二进行操作区别在于步骤三 : 在app模块的build.gradle中增加如下配置 :gradle.projectsEvaluated{/**tasks.withTypeJavaCompile().configureEach { val frameworkJar file(libs/framework.jar) val bootstrapClasspath options.bootstrapClasspath?.files?.toMutableList() ?: mutableListOf() bootstrapClasspath.add(0, frameworkJar) options.bootstrapClasspath files(bootstrapClasspath) }**/tasks.withTypeorg.jetbrains.kotlin.gradle.tasks.KotlinCompile().configureEach{valframeworkJarfile(libs/framework.jar)// 将 framework.jar 添加到 libraries (classpath) 的最前面libraries.setFrom(files(frameworkJar)libraries)}}再次运行项目可以发现powerManager.wakeUp和wifiManager.connect这种隐藏API就不再报错了能够正常运行了。