文章
expo 集成aar文件编译出错排查记录
第一部分
这是一个非常经典的 Android 构建问题,特别是在开发 React Native 或 Expo 模块时经常遇到。 核心原因分析 为什么 JPush 可以,而你的不行? 文件类型不同: JPush 使用的是 .jar 文件 (jpush-android-5.9.0.jar)。.jar 只包含 Java 代码,Android 构建工具允许将 .jar 直接打包进 Library 模块中。 你的模块 使用的是 .aar 文件 (AIKit.aar)。.aar 包含代码、资源文件(图片、布局)、Manifest 等。Android Gradle Plugin (AGP) 禁止在 Library 模块(你的 Expo 模块本质上是一个 Library)中直接通过文件路径 (files(...)) 依赖本地 .aar。 错误含义: 错误信息 Direct local .aar file dependencies are not supported when building an AAR 明确指出了这一点。构建系统不知道如何完美地将一个本地 .aar 的资源合并到另一个正在构建的 .aar 中,为了防止产物损坏,它直接报错阻断了。 解决方案 要解决这个问题,你需要欺骗 Gradle,让它认为这是一个从仓库(Repository)下载的依赖,而不是一个本地文件依赖。 请修改 modules/iflytek-waken/android/build.gradle 文件,按以下步骤操作: 添加 repositories { flatDir { ... } } 配置。 将 implementation files(...) 改为 implementation(name: '...', ext: 'aar')。
apply plugin: 'com.android.library'
group = 'expo.modules.iflytekwaken'
version = '0.7.6'
// 1. 添加这个 repositories 块,告诉 Gradle 在 libs 目录下寻找依赖
repositories {
flatDir {
dirs 'libs'
}
}
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
apply from: expoModulesCorePlugin
applyKotlinExpoModulesCorePlugin()
useCoreDependencies()
useExpoPublishing()
def useManagedAndroidSdkVersions = false
if (useManagedAndroidSdkVersions) {
useDefaultAndroidSdkVersions()
} else {
buildscript {
ext.safeExtGet = { prop, fallback ->
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
}
project.android {
compileSdkVersion safeExtGet("compileSdkVersion", 36)
defaultConfig {
minSdkVersion safeExtGet("minSdkVersion", 24)
targetSdkVersion safeExtGet("targetSdkVersion", 36)
}
}
}
android {
namespace "expo.modules.iflytekwaken"
defaultConfig {
versionCode 1
versionName "0.7.6"
}
lintOptions {
abortOnError false
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
// 2. 修改这里:不要使用 files('libs/AIKit.aar')
// implementation files('libs/AIKit.aar')
// 改为使用 name 和 ext 的方式引用,配合上面的 flatDir
implementation(name: 'AIKit', ext: 'aar')
}
关于 JPush 的警告 日志中关于 JPush 的大量 WARNING: ... D8: Expected stack map table ... 是因为 JPush 的 jar 包比较老或者经过了混淆,导致新的 D8 编译器(Android 的字节码编译器)在处理时发出的警告。这些只是警告,不会导致编译失败,你可以忽略它们。导致失败的唯一原因是上面的 .aar 依赖问题。
第二部分
我已经帮你修改了配置,解决了本地 AAR 依赖导致的编译错误。 修改内容总结 修改了模块的 build.gradle (modules/iflytek-waken/android/build.gradle): 添加了 repositories { flatDir { dirs 'libs' } },告诉 Gradle 在模块的 libs 目录查找依赖。 将 implementation files('libs/AIKit.aar') 修改为 implementation(name: 'AIKit', ext: 'aar')。这是关键步骤,它将本地文件依赖伪装成仓库依赖,从而绕过了 Android Gradle Plugin 对 "Library 模块依赖本地 AAR" 的限制。
修改了主工程的 build.gradle (android/build.gradle): 在 allprojects 的 repositories 中添加了 flatDir { dirs "$rootDir/../modules/iflytek-waken/android/libs" }。原因:虽然模块内部知道去哪里找 AIKit.aar,但当主应用(app)编译并合并所有依赖时,它也需要知道去哪里下载或找到这个 AIKit 依赖。如果不加这一步,主应用编译时会报 "Could not find :AIKit:" 的错误。 接下来你可以做什么 现在你可以重新尝试运行编译命令了: ./gradlew aR 或者如果你是在 Expo 环境下开发: npx expo run:android 关于 JPush 的那些 WARNING 日志可以忽略,它们不会影响最终的构建成功
第三部分
这个错误 Could not find :AIKit: 证实了我之前的推测:虽然你在模块内部配置了 flatDir,但是主应用(:app)在构建时,需要解析所有依赖树,而它不知道去哪里找这个 AIKit。 我已经帮你修改了根目录下的 android/build.gradle 文件,添加了 flatDir 配置,指向你的模块的 libs 目录。 修复内容 在 /Users/xuzhibin/Desktop/project/xiaoNuoJiaHuApp/android/build.gradle 的 allprojects 块中添加了: flatDir { dirs "$rootDir/../modules/iflytek-waken/android/libs" } 这样,整个项目(包括主应用)都能找到位于 modules/iflytek-waken/android/libs 下的 AIKit.aar 文件了。 现在请再次尝试运行编译命令。