如何在Android主项目中引用库项目中使用的aar文件

13

我的项目包括一些库项目。库使用一些aar文件,其依赖关系已在模块gradle文件中定义。我在将这个库包含到我的项目中时遇到了问题。

如果我在app->lib中保留重复的aar文件并在app->gradle文件中定义它们的依赖关系,则不会出现问题。但这不应该是正确的方法。

请查找下面的错误:

配置项目“:app”时出错。

Could not resolve all dependencies for configuration ':app:_qaDebugCompile'. Could not find :api-release:. Searched in the following locations:
         https://jcenter.bintray.com//api-release//api-release-.pom
         https://jcenter.bintray.com//api-release//api-release-.aar
         file:/D:/sample/sample-android-app/app/libs/api-release-.aar
         file:/D:/sample/sample-android-app/app/libs/api-release.aar
     Required by:
         sample-android-app:app:unspecified > sample-android-app:misnapworkflow:unspecified
请查看以下项目结构:
sample
|-- app
|-- misnapworkflow
    |
    |-- lib
        |-- api-release.aar

在应用程序的Gradle文件中,已经提到了以下内容来包含项目:

dependencies { compile project(':misnapworkflow') }

请查找下面的misnapworkflow Gradle文件:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 23
        consumerProguardFiles 'proguard-rules.pro'
    }

    lintOptions {
        abortOnError false
    }

    // Publish both debug and release libraries
    publishNonDefault true

    buildTypes {
        debug {
            debuggable true
            jniDebuggable true
            minifyEnabled false
            shrinkResources false
            testCoverageEnabled true
        }

        release {
            signingConfig signingConfigs.debug
            debuggable false
            jniDebuggable false
            minifyEnabled true
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

task grantPermissions(type: Exec, dependsOn: 'installDebugTest') {
    logger.warn('Granting permissions...')
    commandLine "adb shell pm grant com.miteksystems.misnap.misnapworkflow.test android.permission.WRITE_EXTERNAL_STORAGE".split(' ')
    commandLine "adb shell pm grant com.miteksystems.misnap.misnapworkflow.test android.permission.CAMERA".split(' ')
    logger.warn('Permissions granted.')
}

tasks.whenTaskAdded { task ->
    if (task.name.startsWith('connected')
            || task.name.startsWith('create')) {
        task.dependsOn grantPermissions
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:23.0.1'

    // Add dependency for MiSnap external API
    compile(name: 'api-release', ext: 'aar')

    // Add dependency for MiSnap
    compile(name: 'misnap-release', ext: 'aar') {
        exclude module: 'appcompat-v7'
    }

    // Eventbus dependency
    compile 'de.greenrobot:eventbus:2.4.0'

    // Add OPTIONAL dependency for Manatee
    compile(name: 'manatee-release', ext: 'aar')

    compile(name: 'cardio-release', ext: 'aar')
}

repositories {
    flatDir {
        dirs 'libs'
    }
}

你解决了这个问题吗?我也遇到了完全相同的问题。如果我不将aar文件复制到应用程序模块中,它就无法工作。我在应用gradle中有jcenter和flatDir指令,但没有任何区别。 - Roberto
@Lancelot,我已经在我的项目中解决了这个问题,请查看下面的答案。 - aldok
1
@aldok 谢谢!!!已经好久没用它了,不是很需要了。还是谢谢你 :) - Roberto
5个回答

25
aar 文件不包含传递依赖项,也没有描述库所使用依赖的 pom 文件。 这意味着,如果您正在使用 flatDir 仓库导入 aar 文件,您必须在项目中指定依赖项
您应该使用一个maven 仓库(您必须将库发布到私有或公共 maven 仓库),这样您就不会遇到同样的问题。
在这种情况下,Gradle 使用包含依赖项列表的 pom 文件下载依赖项。

如果库模块使用了一些aar文件,但是应用程序模块中没有使用到,那么我是否仍然需要保留两个相同的aar文件?请注意,在我的情况下,库模块是第三方库。因此,我不想修改库模块的gradle文件。 - Manish
您可以使用相同的aar文件而无需复制它。无论如何,您不必修改库的gradle文件,但是您必须在应用程序build.gradle文件中具有依赖项。 - Gabriele Mariotti
@Manish,你需要在flatDir中指定aar文件的文件夹,并在build.gradle文件中添加jcenter repo。 - Gabriele Mariotti
您可以通过以下方式在模块中指定aar: flatDir { dirs "${rootProject.projectDir}/path/to/aar" } - enyciaa
@GabrieleMariotti,这次我遇到了Maven的问题。我已经将一个库模块(比如lib1)发布到了jfrog上。现在另一个库模块(lib2)依赖于lib1模块。其他库模块(lib3、lib4)和应用程序模块依赖于lib2,并且能够使用lib1而不必添加lib1到依赖项中。但是自从lib2通过jfrog仓库引用lib1以来,所有其他模块(lib3、lib4、app)也必须添加lib1到依赖项中,否则会出现错误,无法解析lib1:1.0.0。 - Manish
显示剩余2条评论

7

针对 Android Studio:

按照以下步骤进行操作:

第一步:

导入 .aar

文件 ---> 新建 ---> 新建模块 ---> (选择) 导入 .JAR/.AAR 包 ---> 下一步 --->(选择 .aar 文件然后) 完成

现在你的现有项目已被导入。

第二步:

添加 dependencies

文件---> 项目结构 ---> (现在你将在左侧底部获得模块列表。) ---> (选择 app 模块) ---> 选择依赖项选项卡 ---> 点击 (+) 按钮 ---> 选择模块依赖项 ---> (选择你添加的模块) ---> ok ---> ok

To add dependencies(1) add dependencies(2)

注意:要检查依赖项是否已添加,

你的 build.gradle 应该如下所示:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:design:23.2.1'
    compile 'com.squareup.picasso:picasso:2.5.0'
    compile project(':ScreenSharingSDK')
}

嗨Pramod,所有项目依赖关系已经定义好了,但是有一些aar文件被库项目本身使用。这些aar文件在模块文件夹的lib文件夹中,但gradle正在搜索应用程序的lib文件夹中的这些文件。 - Manish

2
如果我在app->lib中保留重复的aar文件,并在app->gradle文件中定义它们的依赖关系,那就没有问题。但这不应该是正确的方法。
您说得对,您的app不应该在build.gradle中定义AAR库依赖项。这是第三方库(如OkHttp、Picasso或RxJava)的常见做法。实际上,这些库有自己的依赖关系,就像您的AAR库一样。
那么,为什么OkHttp、Picasso或RxJava不要求您的应用程序包括它们的依赖关系呢?因为它们已经在POM文件中包含了它们的依赖关系。POM文件包含了AAR的配置文件,包括您的构件、组名称、版本及其依赖项。
让我们以OkHttp为例。OkHttp及其依赖项存储在其他人的计算机上。转到mvnrepository.com并搜索OkHttp。

Ok Http Maven

你会找到OkHttp及其POM文件。
<project>
   <modelVersion>4.0.0</modelVersion>
   <parent>...</parent>
   <artifactId>okhttp</artifactId>
   <name>OkHttp</name>
   <dependencies>
      <dependency>
         <groupId>com.squareup.okio</groupId>
         <artifactId>okio</artifactId>
      </dependency>
      <dependency>
         <groupId>com.google.android</groupId>
         <artifactId>android</artifactId>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>com.google.code.findbugs</groupId>
         <artifactId>jsr305</artifactId>
         <scope>provided</scope>
      </dependency>
   </dependencies>
   <build>...</build>
</project>

当您在build.gradle()中包含一个库时,Gradle会在顶级build.gradle中定义的存储库中搜索该库。对于OkHttp,它被存储在mavenCentral()中。
repositories {
    google()
    mavenCentral()
    jcenter()
}

Gradle会自动下载依赖项,您不需要在应用程序项目中指定库的依赖关系。
但这并不是正确的方法。
正确的方法是:
1. 将库及其依赖项存储在Maven仓库中。 您可以使用本地Maven仓库、托管自己的Maven仓库,或将库发布到Maven Central或Bintray。inthecheesefactory有一个很好的教程。
2. 为您的库创建POM文件。
当您部署AAR时,必须包含POM文件。它可以手动完成。
mvn deploy:deploy-file \
    -DgroupId=com.example \
    -DartifactId=your-library \
    -Dversion=1.0.1 \
    -Dpackaging=aar \
    -Dfile=your-library.aar \
    -DpomFile=path-to-your-pom.xml \
    -DgeneratePom=true \
    -DupdateReleaseInfo=true \
    -Durl="https://mavenUserName:mavenPassword@nexus.example.com/repository/maven-releases/"

或者使用 android-maven-publish Gradle 插件。
gradle yourlibrary:assembleRelease yourlibrary:publishMavenReleaseAarPublicationToMavenRepository

将你的库分享给同行:
在应用层级的 build.gradle 中添加你的库的 GAV
dependencies{
    implementation "com.example:yourlibrary:1.0.1"
}

你和你的同行现在应该能够使用yourlibrary了。

1
在我的情况下,以下内容有效:
将您的 .aar 文件放入 libs 目录中(如果需要,请创建),然后在您的 build.gradle(app level) 中添加以下代码:
    repositories { 
        flatDir { 
            dirs 'libs' 
        } 
    } 

    dependencies { 
        compile fileTree(dir: 'libs', include: ['*.jar']) 
        compile(name:'your_arr_filename', ext:'aar') 
    } 

1

Monika Moon帮助我找到了正确的路径,但我没有足够的声望点来在上面进行内联评论。叹气。

因此,在2020年使用Android Studio 3.5.3构建的默认Android应用程序将通过项目视图具有以下项目结构:

--[yourAppName]
  --[app]
  --[gradle]
  build.gradle <this is the TOP LEVEL one and NOT the one you normally mess with>

在顶层build.gradle文件中添加'flatDir'项:
allprojects {
        repositories {
            google()
            jcenter()

            // needed so it picks up my aar files
            flatDir {
                dirs 'libs'
            }
        }
}

然后在您上面显示的“应用程序”文件夹中。 您将拥有这两个关键资源:

 -- [libs] folder where you should drop your aar files
 build.gradle file that is the one you add your aar dependencies to.

默认的项目构建已经包含了一个 'libs' 的引用,但是如果你的版本没有的话,你需要添加以下内容:
dependencies {
    implementation fileTree(dir: './libs', include: ['*.jar'])
    implementation(name: 'fileNameBeforeExtension', ext:'aar')

这是干净的,按预期工作。
我使用的AAR文件是内部硬件的定制版本,永远不会在公共存储库中出现。

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