Gradle: How to manage dependencies


Gradle makes easy to include external binaries or other library modules to your build as dependencies. The dependencies can be located on your machine or in a remote repository, and any transitive dependencies they declare are automatically included as well. Dependencies are usually managed at the Module-level inside dependencies block in build.gradle file.

Once you have lots of modules, build.gradle file can quickly get messy from dependencies. So In this article, I’ll show a quick way of making Gradle clean and easy to maintain.


Manage dependencies versions

Let’s say our Module-level build.gradle looks like as mentioned below in that you can see most of the libraries have similar library version.

apply plugin: 'com.android.application'
android {
      ...
    defaultConfig {...}
    buildTypes {...}
    productFlavors {...}
}
...

dependencies {
    // Android supported libraries
    compile 'com.android.support:appcompat-v7:25.0.0'
    compile 'com.android.support:design:25.0.0'
    compile 'com.android.support:cardview-v7:25.0.0'
    compile 'com.android.support:gridlayout-v7:25.0.0'

    //Google play services
    compile 'com.google.android.gms:play-services:10.2.0'
    compile 'com.google.android.gms:play-services-fitness:10.2.0'
    compile 'com.google.android.gms:play-services-wearable:10.2.0'

    // other dependencies
    ...
}


It is very difficult to manage versions of different libraries. Here we can leverage Gradle’s extra property. For this Gradle provides ext block where we can define our common property values and use those property values in dependencies.


apply plugin: 'com.android.application'
android {
      ...
    defaultConfig {...}
    buildTypes {...}
    productFlavors {...}
}
...

ext {
    supportLibraryVersion = '25.0.0'
    playServiceVersion = '10.2.0'
}

dependencies {
    // Android supported libraries
    compile "com.android.support:appcompat-v7:$supportLibraryVersion"
    compile "com.android.support:design:$supportLibraryVersion"
    compile "com.android.support:$supportLibraryVersion"
    compile "com.android.support:gridlayout-v7:$supportLibraryVersion"

    //Google play services
    compile "com.google.android.gms:play-services:$playServiceVersion"
    compile "com.google.android.gms:play-services-fitness:$playServiceVersion"
    compile "com.google.android.gms:play-services-wearable:$playServiceVersion"
   
    ...
}


In above sample code ext block contains two property field playServiceVersion and supportLibraryVersion. Notice that instead of version number, we added $ with its version property and also changed single quotes to double quotes.

When you have multiple modules and you want to use similar version to them also then just move ext block from Module-level build.gradle to Top-level (root) build.gradle.


buildscript {
    ...
}

allprojects {
    ...
}
...

ext {
    supportLibraryVersion = '23.4.0'
    playServicesVersion = '9.2.1'
}

Now your different modules build.gradle will looks like:

apply plugin: 'com.android.application'
android {
      ...
    defaultConfig {...}
    buildTypes {...}
    productFlavors {...}
}
...

dependencies {
    // Android supported libraries
    compile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion"
    compile "com.android.support:design:$rootProject.supportLibraryVersion"
    compile "com.android.support:$rootProject.supportLibraryVersion"
    compile "com.android.support:gridlayout-v7:$rootProject.supportLibraryVersion"

    //Google play services
    compile "com.google.android.gms:play-services:$rootProject.playServiceVersion"
    compile "com.google.android.gms:play-services-fitness:$rootProject.playServiceVersion"
    compile "com.google.android.gms:play-services-wearable:$rootProject.playServiceVersion"
   
    ...
}

Here "com.android.support:appcompat-v7:$supportLibraryVersion" changed to   
"com.android.support:appcompatv7:$rootProject.supportLibraryVersion"

This is just the basic use of ext block. You can also configure other common properties like – versionName, versionCode, minSdkVersion etc in it.


Manage File Dependencies

Adding JARs

To add the JARs dependency in your module you simply kept it in the libs folder and add the below compile dependency:

apply plugin: 'com.android.application'
android {
      ...
    defaultConfig {...}
    buildTypes {...}
    productFlavors {...}
}
...

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



Adding specific JARs from defined folder

Gradle also provides the flexibility to configure and only import the JARs from our choice and also from defined directory. Let’s say we want “first.jar”, “second.jar” from “mylibrary” directory. This directory is located at project level. So this can be achieve like:

apply plugin: 'com.android.application'
android {
      ...
    defaultConfig {...}
    buildTypes {...}
    productFlavors {...}
}
...

dependencies {
    // Import selected JARs from mylibrary folder
    compile fileTree(include: ['first.jar','second.jar'], dir: '../mylibrary')
    ...
}

Adding AARs

Let’s say we have kept AAR file (mylib.aar) in libs folder, so in Top level build.gradle we need to specify flatDir as following:

buildscript {
    ...
}

allprojects {
   repositories {
      jcenter()
      flatDir {
        dirs 'libs'
      }
   }
}

And add the below compile dependency in the Module level build.gradle:

apply plugin: 'com.android.application'
android {
      ...
    defaultConfig {...}
    buildTypes {...}
    productFlavors {...}
}
...

dependencies {
       compile(name:'mylib', ext:'aar')
    ...
}

This is all about Gradle dependencies. In general to maintain your Gradle, define your properties in the root level/ top level build.gradle and use it into different modules. You can also read my previous articles on Gradle for more details.

To find more interesting topics on Software development follow me at https://medium.com/@ankit.sinhal.


Comments

Popular posts from this blog

Android O: Impact On Running Apps And Developer Viewpoint

Android Performance: Avoid using ENUM on Android

Local Broadcast, less overhead and secure in Android