Jay Taylor's notes

back to listing index

How to manage the support libraries in a multi-module projects. Thanks to Fernando Cejas (http://fernandocejas.com/)

[web search]
Original source (gist.github.com)
Tags: dependency-management build-pipeline gradle
Clipped on: 2020-03-06

Skip to content
How to manage the support libraries in a multi-module projects. Thanks to Fernando Cejas (http://fernandocejas.com/)

Centralize the support libraries dependencies in gradle

Working with multi-modules project, it is very useful to centralize the dependencies, especially the support libraries.

A very good way is to separate gradle build files, defining something like:

root
  --gradleScript
  ----dependencies.gradle
  --module1
  ----build.gradle
  --build.gradle

In gradleScript/dependecies.gradle:

ext {
    //Version
    supportLibrary = '22.2.1'

    //Support Libraries dependencies
    supportDependencies = [
            design           :         "com.android.support:design:${supportLibrary}",
            recyclerView     :         "com.android.support:recyclerview-v7:${supportLibrary}",
            cardView         :         "com.android.support:cardview-v7:${supportLibrary}",
            appCompat        :         "com.android.support:appcompat-v7:${supportLibrary}",
            supportAnnotation:         "com.android.support:support-annotations:${supportLibrary}",
    ]
}

In the top level file build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
    }
}

// Load dependencies
apply from: 'gradleScript/dependencies.gradle'

In the module1/build.gradle:

// Module build file

dependencies {
    //......
    compile supportDependencies.appCompat
    compile supportDependencies.design
}
1 // Module build file
2
3 dependencies {
4 //......
5 compile supportDependencies.appCompat
6 compile supportDependencies.design
7 }
1 // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 buildscript {
3 repositories {
4 jcenter()
5 }
6 dependencies {
7 classpath 'com.android.tools.build:gradle:1.2.3'
8 }
9 }
10
11 // Load dependencies
12 apply from: 'dependencies.gradle'
1 ext {
2 //Version
3 supportLibrary = '22.2.1'
4
5 //Support Libraries dependencies
6 supportDependencies = [
7 design : "com.android.support:design:${supportLibrary}",
8 recyclerView : "com.android.support:recyclerview-v7:${supportLibrary}",
9 cardView : "com.android.support:cardview-v7:${supportLibrary}",
10 appCompat : "com.android.support:appcompat-v7:${supportLibrary}",
11 supportAnnotation: "com.android.support:support-annotations:${supportLibrary}",
12 ]
13 }
Image (Asset 2/22) alt=

AkshayChordiya commented on Jul 22, 2015
edited

Thank you so much

Image (Asset 3/22) alt=

jfabrix101 commented on Sep 13, 2015

Very useful tip

Image (Asset 4/22) alt=

IlyaEremin commented on Feb 11, 2016

Also, you can union all supportDependencies in following way:
compile supportDependencies.values()
instead of writing them one by one

Image (Asset 5/22) alt=

lopspower commented on Apr 25, 2016
edited

Doesn't work for me.

I have:

Error:(48, 0) Cannot convert a null value to an object of type Dependency.
The following types/formats are supported:
  - Instances of Dependency.
  - String or CharSequence values, for example 'org.gradle:gradle-core:1.0'.
  - Maps, for example [group: 'org.gradle', name: 'gradle-core', version: '1.0'].
  - FileCollections, for example files('some.jar', 'someOther.jar').
  - Projects, for example project(':some:project:path').
  - ClassPathNotation, for example gradleApi().

Because of:

dependencies {
    // SUPPORT
    compile supportDependencies.appcompat
    compile supportDependencies.design
    compile supportDependencies.recyclerview
    ...
}

HELP :(

Image (Asset 6/22) alt=

dennisdrew commented on Apr 26, 2016

@lopspower you're not accessing the properties correctly. If you notice in the dependencies.gradle, the dependencies are declared as part of the ext closure. Also, if you notice in the root build.gradle, the dependencies.gradle is applied. Therefore, the dependency values are located on the root project's ext closure. Therefore, you would access them:
compile rootProject.ext.supportDependencies.appcompat

Image (Asset 7/22) alt=

cosic commented on May 5, 2016
edited

There is a good sample from artem-zinnatullin

Image (Asset 8/22) alt=

samardzija commented on Oct 13, 2016

@lopspower you wrote supportDependencies.appcompat and it should be supportDependencies.appCompat. It is case sensitive :)

Image (Asset 9/22) alt=

GitHubMurt commented on Dec 27, 2016
edited

You may also build your grade:app in following manner:

android{
[...]
ext{
    supportLibrary = '25.1.0'
    playServices = '9.8.0'
    firebase = playServices
}
dependencies {
   [...]
    compile "com.google.android.gms:play-services-location:${playServices}"
    compile "com.google.android.gms:play-services-maps:${playServices}"
    compile "com.google.firebase:firebase-core:${firebase}"
    compile "com.google.firebase:firebase-messaging:${firebase}"

    compile "com.android.support:appcompat-v7:${supportLibrary}"
    compile "com.android.support:design:${supportLibrary}"
    compile "com.android.support:palette-v7:${supportLibrary}"
}

Just don't forget to wrap dependencies in " " instead of ' '

Image (Asset 10/22) alt=

HamzehSoboh commented on Dec 27, 2016

Worked like a charm!

Image (Asset 11/22) alt=

ruijun commented on May 31, 2017

awsome tip !!

Image (Asset 12/22) alt=

IHNEL commented on Jul 10, 2017

By this way Android Studio doesn't notify for newer version of dependencies.

Image (Asset 13/22) alt=

renhuihhh commented on Sep 3, 2017

excellent

Image (Asset 14/22) alt=

quezak commented on Jan 11, 2018

Very nice!
Is it possible to similarily extract "complex" dependencies to another file, in a way they can be included with one line or together with a whole list of deps? Two examples:

    compile('com.crashlytics.sdk.android:crashlytics:2.6.7@aar') {
        transitive = true;
    }
    
    compile('com.github.tony19:logback-android-classic:1.1.1-6') {
        exclude group: 'com.google.android', module: 'android'
    }

Best I can think of is just replacing the full package-and-version leaving the rest intact: compile(libs.someVar) { ... }, but then I can't use that dependency together with others in a list, like you did with compile supportDependencies.values().

Image (Asset 15/22) alt=

quezak commented on Jan 11, 2018
edited

Another question: is there a way for Android Studio to highlight dependencies with new versions using this method, same as they were highlighted in build.gradle originally? Same question for auto-detecting changes in the dependencies.gradle file (if I change it, there is no prompt to do a gradle sync, like when changing any build.gradle file).

Image (Asset 16/22) alt=

vishnuharidas commented on Jan 30, 2018

That's a very useful gist!

Image (Asset 17/22) alt=

Belka1000867 commented on Jan 10, 2019

Another question: is there a way for Android Studio to highlight dependencies with new versions using this method, same as they were highlighted in build.gradle originally? Same question for auto-detecting changes in the dependencies.gradle file (if I change it, there is no prompt to do a gradle sync, like when changing any build.gradle file).

+1 Also interested in this.

Image (Asset 18/22) alt=

Qw4z1 commented on Feb 11, 2019

@quezak and @Belka1000867 compile (and implementation) is a function taking a string as an agrument. So in the same way as you can use the vars directly, i.e. implementation thirdParty.crashlytics you can also use them as such:

    implementation(thirdParty.crashlytics) {
        transitive = true
    }
Image (Asset 19/22) alt=

abeemukthees commented on Feb 15, 2019

Another question: is there a way for Android Studio to highlight dependencies with new versions using this method, same as they were highlighted in build.gradle originally? Same question for auto-detecting changes in the dependencies.gradle file (if I change it, there is no prompt to do a gradle sync, like when changing any build.gradle file).

Is there any way to highlight new versions by using this approach?

Image (Asset 20/22) alt=

OlukaDenis commented on May 2, 2019

Thanks a lot. This was helpful

Image (Asset 21/22) alt=

igorescodro commented on Jun 12, 2019

@abeemukthees, @Belka1000867 and @quezak, you can use the following library to check for updates: gradle-versions-plugin.

It does not make the dependency yellow, but it generates a report with all updates, like this:

 - com.android.tools.lint:lint-gradle [26.4.1 -> 26.6.0-alpha03]
     https://developer.android.com/studio
 - com.google.android.material:material [1.0.0 -> 1.1.0-alpha07]
     http://developer.android.com/tools/extras/support-library.html
 - com.pinterest:ktlint [0.32.0 -> 0.33.0]
     https://github.com/pinterest/ktlint
 - io.gitlab.arturbosch.detekt:detekt-cli [1.0.0-RC14 -> 1.0.0-RC15]
     https://arturbosch.github.io/detekt
 - io.reactivex.rxjava2:rxandroid [2.1.0 -> 2.1.1]
     https://github.com/ReactiveX/RxAndroid
 - io.reactivex.rxjava2:rxjava [2.2.0 -> 2.2.9]
     https://github.com/ReactiveX/RxJava
 - junit:junit [4.12 -> 4.13-beta-3]
     http://junit.org

It is better than check one by one manually.

Image (Asset 22/22) alt= Add header text Add bold text <ctrl+b> Add italic text <ctrl+i>
Insert a quote Insert code Add a link <ctrl+k>
Add a bulleted list Add a numbered list Add a task list
Directly mention a user or team Reference an issue or pull request
Attach files by dragging & dropping, selecting or pasting them. Styling with Markdown is supported