如何在Android模块之间共享依赖项?

50

我有一个安卓应用程序模块(app)和一个安卓库模块(library)。这两个模块都包含相同的依赖项:

dependencies {
    compile 'com.squareup.okhttp:okhttp:2.4.0'
    compile 'com.squareup.retrofit:retrofit:1.9.0'
    compile 'io.reactivex:rxjava:1.0.13'
    compile 'io.reactivex:rxandroid:0.25.0'
}

但是当我尝试将这个块添加到项目的build.gradle中时,它抱怨不知道“compile”DSL。

编辑:我想把这个依赖块放在项目的build.gradle中,以避免在每个模块的build.gradle中重复。


可能是android - gradle多项目包含和排除库的重复问题。 - Jared Burrows
不,我在询问如何在模块之间共享依赖项,以避免在每个模块中重复它们。 - Andrew
6个回答

127

从Gradle插件版本3.0.0开始有更好的方法来处理这个问题。我们可以控制每个依赖项是否仅适用于当前模块,还是适用于当前模块和依赖于它的任何模块。这将允许我们在项目中跨模块轻松共享依赖项。

下面是我们过去如何声明依赖关系的方式:

  • compile 'example.dependency:1.0.0'

以下是应该替换compile的新配置:

  • implementation 'example.dependency:1.0.0' --> 此依赖项仅在此模块中使用
  • api 'example.dependency:1.0.0' --> 此依赖项也将在任何依赖于此模块的构建中可用

以下是如何在你提到的架构中实现。假设我们有一个名为'library'的模块,被'app'模块使用,我们可以使用api配置声明应与依赖它的任何模块共享该依赖项。

'library'模块的build.gradle文件:

dependencies {

    // dependencies marked 'implementation' will only be available to the current module
    implementation 'com.squareup.okhttp:okhttp:2.4.0'

    // any dependencies marked 'api' will also be available to app module
    api 'com.squareup.retrofit:retrofit:1.9.0'
    api 'io.reactivex:rxjava:1.0.13'
    api 'io.reactivex:rxandroid:0.25.0'
}

app 模块 build.gradle 文件:

dependencies {

    // declare dependency on library module
    implementation project(':library')

    // only need to declare dependencies unique to app 
    implementation 'example.dependency:1.0.0'
}

请查看此指南获取更多信息和图表。


1
没能使它工作。完全按照相同的步骤进行操作,我也在库中使用了Retrofit,但仍然无法正常运行。当我将我的库模块导入为.aar文件后,在编译成功后,在设备上会出现类未找到异常并崩溃。有什么提示吗? - Burak Day
嗨 @Jules...你能否回答我的问题https://dev59.com/Lq3la4cB1Zd3GeqPMWqF? - Abdulmalek Dery
1
kapt 怎么样? - Myk

11
依赖块(闭包)需要使用 DependencyHandler 作为代理。你需要将每个项目的 DependencyHandler 传递给 project Gradle 构建文件中的共享依赖项。 project build.gradle
ext.sharedGroup = {dependencyHandler->
    delegate = dependencyHandler

    compile 'com.squareup.okhttp:okhttp:2.4.0'
    compile 'com.squareup.retrofit:retrofit:1.9.0'
    compile 'io.reactivex:rxjava:1.0.13'
    compile 'io.reactivex:rxandroid:0.25.0'
}

应用 build.gradle

dependencies {
    sharedGroup dependencies
}

参考 https://github.com/b1uec0in/DependencyVersionResolver

(查看2.使用默认依赖组。此示例解释了为具有多个模块的大型项目共享库版本、sdk 版本等许多其他提示。)


6
你可以在库模块中定义共享的Gradle依赖项,如果应用模块有这个库作为依赖项,就不需要重复指定所有内容。进一步地,你可以创建一个“公共”模块,需要共享的Gradle依赖项,并且应用和库模块都需要使用该公共模块。

5
你可以这样做,project build.gradle指定所需的依赖项作为变量名,然后在app build.gradle文件中只需要包含变量名即可。当版本号更改时,这非常有用,因为你不想编辑每个模块!
buildscript {
    ext {
        googlePlayServicesVersion = '7.5.0'
        supportLibVersion = '22.2.0'
    }
... (the rest of your repositories/dependency info here) ...
}

ext {
    minSdkVersion=16
    targetSdkVersion=21
    buildToolsVersion='22.0.1'
    compileSdkVersion=21

    //Android Dependencies
    supportV4 = 'com.android.support:support-v4:' + supportLibVersion
    supportAnnotations = 'com.android.support:support-annotations:' + supportLibVersion
    recyclerView = 'com.android.support:recyclerview-v7:' + supportLibVersion
    cardView = 'com.android.support:cardview-v7:' + supportLibVersion
    palette = 'com.android.support:palette-v7:' + supportLibVersion
    appCompat = 'com.android.support:appcompat-v7:' + supportLibVersion
    multidex = 'com.android.support:multidex:1.0.1'
    appCompat = 'com.android.support:appcompat-v7:' + supportLibVersion
    supportDesign = 'com.android.support:design:' + supportLibVersion
    playServicesAnalytics = 'com.google.android.gms:play-services-analytics:' + googlePlayServicesVersion
}

应用程序 build.gradle 文件

dependencies {
   compile rootProject.ext.supportV4
    compile rootProject.ext.appCompat
    compile rootProject.ext.supportAnnotations
    compile rootProject.ext.recyclerView
    compile rootProject.ext.cardView
    compile rootProject.ext.palette
    compile rootProject.ext.appCompat
    compile rootProject.ext.multidex
    compile rootProject.ext.supportDesign
    compile rootProject.ext.playServicesAnalytics

}

希望这可以帮助您!

这是在Android项目的所有模块中使用依赖项的更好方法。 - silwar
如何处理传递选项? - Anthony

1

使用ext块在根项目模块中共享库

这是一种在android项目的所有模块中使用库的简单方法。

请按照以下步骤操作:

  1. 在根项目gradle文件中添加ext块(用于定义项目的额外属性)
  2. 在ext块中使用变量名称添加常用库,例如:name = [libraries without implementation keyword]
  3. 在模块级别中使用implementation和变量名称来使用此ext块,例如:implementation variable_name

请参阅下面的代码以获取完整实现

build.gradle:project

buildscript {
... (the rest of your repositories here) ...
}

ext { **// ext block start here**




appModuleLibraries = [
            commonLibraries,
            /*Projects*/
            project(':hco-cutout'),
            project(':utils')

    ]

commonLibraries = [
        /*Android Libs*/
        'androidx.core:core-ktx:1.7.0',
        'androidx.appcompat:appcompat:1.4.1',
        'com.google.android.material:material:1.5.0',
        'androidx.constraintlayout:constraintlayout:2.1.3',
        /*Gesture viw for image zooming */
        'com.alexvasilkov:gesture-views:2.5.2',


]
cutoutModulleLibraries = [
        commonLibraries,
        project(':utils'),
        // Selfie segmentation
        'com.google.mlkit:segmentation-selfie:16.0.0-beta4',

        /*checker board drawable*/
        'com.github.duanhong169:checkerboarddrawable:1.0.2',
]
} **// ext block end here**

build.gradle :app

      dependencies {
    
      /*App Module Libraries in root project gradle*/

        implementation appModuleLibraries
    }

build.gradle:切换

 dependencies {
    /*cutout Module Libraries in root project gradle*/

    implementation cutoutModulleLibraries

    implementation project(':utils')

}

希望这有所帮助!

-1

基于 @SMKS 的答案,我更喜欢这个解决方案,因为它具有传递选项能力和简单性。

项目 build.gradle

buildscript {
... (the rest of your repositories/dependency info here) ...
}

ext {
        googlePlayServicesVersion = '7.5.0'
        supportLibVersion = '22.2.0'
}

应用程序 build.gradle 文件

dependencies {
    compile 'com.android.support:support-v4:' + supportLibVersion
    compile ' com.android.support:support-annotations:' + supportLibVersion
    compile = 'com.android.support:recyclerview-v7:' + supportLibVersion {
        transitive = true // do not know if this make sens/interest just for example
    }
   ...
}

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