使用具有Gradle依赖项的库项目时出现Android:ClassNotFoundException

8
我有一个自定义视图库,它可以单独编译和运行(通过库项目内专门为测试目的创建的另一个活动)。然而,当我构建库并将aar导入到另一个项目中(打开模块设置->新建模块->现有aar..),我会得到一个运行时ClassNotFoundException - 异常出现在库正在使用的唯一gradle依赖项上。为什么会发生这种情况?
库gradle文件:
    apply plugin: 'com.android.library'

    android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile 'com.googlecode.libphonenumber:libphonenumber:7.2.1'
}

我得到的错误信息:

Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.i18n.phonenumbers.PhoneNumberUtil" on path: DexPathList[[zip file..

"somegradledependency" 是什么意思,@Jon? - Amit Vaghela
@AmitVaghela 抱歉,这是我的混淆尝试,显然我不能在这里使用。我编辑并在上述中添加了库。 - Jon
1个回答

1

aar依赖不像maven/ivy依赖那样在pom或xml文件中捆绑有传递性依赖。当您添加aar依赖项时,gradle无法知道要获取哪些传递性依赖。

在android世界中的一种常见做法是,将传递性依赖项明确添加到使用aar的应用程序中。这可能会变得繁琐,并且有点违背了依赖管理系统的初衷。

有几种解决方法:

1. android-maven插件

有一个第三方gradle插件允许您将aar文件与有效的pom文件一起发布到本地maven存储库中。

2. maven-publish插件

您可以使用标准的maven-publish插件将aar发布到maven存储库,但您必须自己组装pom依赖项。例如:

publications {
    maven(MavenPublication) {
        groupId 'com.example' //You can either define these here or get them from project conf elsewhere
        artifactId 'example'
        version '0.0.1-SNAPSHOT'
        artifact "$buildDir/outputs/aar/app-release.aar" //aar artifact you want to publish

        //generate pom nodes for dependencies
        pom.withXml {
            def dependenciesNode = asNode().appendNode('dependencies')
            configurations.compile.allDependencies.each { dependency ->
                def dependencyNode = dependenciesNode.appendNode('dependency')
                dependencyNode.appendNode('groupId', dependency.group)
                dependencyNode.appendNode('artifactId', dependency.name)
                dependencyNode.appendNode('version', dependency.version)
            }
        }
    }
}

在这两种情况下,一旦aar+pom在Maven仓库中可用,您可以像这样在您的应用程序中使用它:
compile ('com.example:example:0.0.1-SNAPSHOT@aar'){transitive=true}

如果您添加依赖项compile project(:mylib),我不确定及物动词的工作方式。 我会尽快更新此答案以解决此问题。


抱歉,我误解了你的问题。所以你导入了一个aar文件,但是Studio添加了compile project()吗? - RaGe
我制作了一个库项目,它通过gradle具有编译依赖关系。当我单独运行库项目时,它可以正常运行。但是,当我将库项目导入到另一个应用程序中并尝试运行该应用程序时,会出现运行时崩溃并抛出异常。 - Jon
如果我将依赖项添加到应用程序中(并使其成为普通编译 - 而不是传递性),那么它就可以工作。然而,应该有一种方法可以在不重复依赖项的情况下完成这个过程。 - Jon
1
问题在于aar文件没有附带描述其依赖项的pom文件。因此,您的应用程序将不知道要获取哪些依赖项。我写了一个关于生成自己的pom的SO答案,让我去找一下。 - RaGe
我的困惑在于,如果你将一个依赖添加为 project 而不是 aar,我就认为 Gradle 会解决传递依赖关系。我会进行一些研究并更新答案。 - RaGe
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接