'How do I share dependencies between Android modules
I have an Android application module (app) and an Android library module (library). Both app and library contain these same dependencies:
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'
}
However when I try to add that block to the project build.gradle, it complains about not knowing the "compile" DSL.
EDIT: I'm asking about putting this dependencies block in the PROJECT build.gradle, to avoid repeating in each module's build.gradle.
Solution 1:[1]
As of Gradle Plugin version 3.0.0 there is a nicer way to do this. We can control whether each dependency is available for only the current module, or for the current module AND any modules which depend on it. This will allow us to easily share dependencies across modules within a project.
Here's how we used to declare dependencies:
- compile 'example.dependency:1.0.0'
Here are the new configurations which should replace compile:
- implementation 'example.dependency:1.0.0' --> this dependency is only used within this module
- api 'example.dependency:1.0.0' --> this dependency will also be available in any builds that depend on this module
Here's how to do that with the architecture you mentioned in the question. Assuming that we have a module named 'library' that is consumed by the 'app' module, we can use the api configuration to declare that the dependency should be shared with any module that depends on it.
library module 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 module 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'
}
Please see this guide for further information and diagrams.
Solution 2:[2]
The dependencies block(closure) needs DependencyHandler as delegate
You need to pass DependencyHandler of each project to shared dependencies in project gradle.build.
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'
}
app build.gradle
dependencies {
sharedGroup dependencies
}
ref. https://github.com/b1uec0in/DependencyVersionResolver
(see 2. Using default dependency group. This sample explains many other tips for sharing library version, sdk versions ... for large project that have many modules.)
Solution 3:[3]
You could do something like this where the project build.gradle will specify the dependencies needed as variable names then in the app build.gradle files you just need to include the variable names. This is very useful when you have many modules and don't want to edit everyone when a version number changes!
project 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
}
app build.gradle file
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
}
Hope that this helps!
Solution 4:[4]
Based on @SMKS answer, I would prefer this solution for transitive option capability and simplicity
project build.gradle
buildscript {
... (the rest of your repositories/dependency info here) ...
}
ext {
googlePlayServicesVersion = '7.5.0'
supportLibVersion = '22.2.0'
}
app build.gradle file
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
}
...
}
Solution 5:[5]
Share libraries using ext block in the root project module
This is an easy way to use the library across all modules in the android project
Please follow these steps:
- Add ext block (it is used to define extra properties for the project) in root project gradle file
- Add common libraries in with variable name in ext block e.g name = [ libraries without implementation keyword ]
- Used this ext block in module level using implementation and variable name e.g implementation variable_name
See below code for complete implementation
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 :cutout
dependencies {
/*cutout Module Libraries in root project gradle*/
implementation cutoutModulleLibraries
implementation project(':utils')
}
Hope that this helps!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | UnknownStack |
| Solution 3 | SMKS |
| Solution 4 | Anthony |
| Solution 5 | Hamza Khalid |
