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

开发Android库依赖发布问题:引用后遇NoClassDefFoundError

问题描述

我正在开发一个Android库,在项目模块中声明了若干依赖并发布到本地Maven仓库,模块的build.gradle.kts依赖配置如下:

dependencies {
    // Retrofit
    implementation(libs.retrofit)
    implementation(libs.retrofit.gson)
    implementation(libs.okhttp)
    implementation(libs.okhttp.logging)

    // room
    implementation(libs.room.runtime)
    implementation(libs.room.ktx)
    ksp(libs.room.compiler)
    testImplementation(libs.room.testing)

    // Work Manager
    implementation(libs.work.runtime.ktx)

    // Play services
    implementation(libs.play.services.location)

    // DI
    implementation(libs.koin.android)
}

发布配置如下:

publishing {
    publications {
        create<MavenPublication>("release") {
            artifact("$buildDir/outputs/aar/${project.name}-release.aar")
            groupId = "com.mylibrary.android"
            artifactId = "core"
            version = project.extra["baseVersionName"] as String
        }
    }
    repositories {
        maven {
            url = uri("${project.buildDir}/repo")
        }
    }
}

执行./gradlew assembleRelease和./gradlew publish后成功生成AAR文件,但在示例应用中用implementation("com.mylibrary.android:core:0.3.1")引用该SDK时,出现java.lang.NoClassDefFoundError: Failed resolution of:错误。我不希望示例应用单独声明这些依赖,尝试将implementation替换为api但无效,也了解到fat-aar方案,不确定是否正确,想知道处理库依赖的正确方式,以及是否应将依赖随库一同发布。

解决方案

1. 修复发布配置,自动生成依赖元数据

你当前的发布配置直接指定本地AAR文件作为artifact,这种方式不会生成包含依赖信息的pom.xml文件,导致示例应用无法通过依赖传递获取库的依赖。正确的做法是让Gradle自动处理组件发布,修改publishing配置如下:

publishing {
    publications {
        create<MavenPublication>("release") {
            // 替换直接指定aar的方式,使用组件发布
            from(components["release"])
            groupId = "com.mylibrary.android"
            artifactId = "core"
            version = project.extra["baseVersionName"] as String
        }
    }
    repositories {
        maven {
            url = uri("${project.buildDir}/repo")
        }
    }
}

这样Gradle会自动生成包含依赖关系的pom.xml,示例应用引用时会自动拉取所需的传递依赖。

2. 正确区分implementation和api的使用

  • api:用于库对外暴露的依赖,即如果你的库的公共API中直接使用了某个依赖的类型(比如方法参数返回Retrofit的Call对象),就用api声明,这样依赖会传递给示例应用。
  • implementation:用于库内部仅自己使用的依赖,不会传递给上层应用。
    你之前替换implementation为api无效,就是因为发布配置没生成正确的pom文件,现在修复发布配置后,这个区分就能生效。

3. 关于fat-aar方案

除非你的依赖是无法通过Maven仓库访问的私有本地库,否则不推荐使用fat-aar。fat-aar会把所有依赖打包进你的库的AAR中,带来以下问题:

  • 增大库的体积,导致示例应用安装包变大。
  • 容易引发依赖冲突(比如示例应用本身也依赖了相同库的不同版本)。
  • 破坏Maven的依赖传递机制,不符合标准的库发布规范。

4. 验证发布结果

重新执行./gradlew publish后,查看本地Maven仓库中com/mylibrary/android/core/0.3.1目录下的core-0.3.1.pom文件,确认其中包含了你的库的依赖声明。此时示例应用重新同步Gradle后,就能自动获取所需依赖,不会再出现NoClassDefFoundError。

内容的提问来源于stack exchange,提问作者Ziv Kesten

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 08:25:06