文章

expo 集成aar文件编译出错排查记录

浏览: 75评论: 0发布时间: 2025-12-13

第一部分

这是一个非常经典的 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 文件了。 现在请再次尝试运行编译命令。