Use versions.gradle in Android project to manage the dependencies
In Android project, we have to use and manage tons of libraries to accelerate our development. For example, to use Google’s component Room, we may need to import up to 4 libraries.
room.runtime = "androidx.room:room-runtime:$versions.room"
room.compiler = "androidx.room:room-compiler:$versions.room"
room.rxjava2 = "androidx.room:room-rxjava2:$versions.room"
room.testing = "androidx.room:room-testing:$versions.room"
It’s fine if the project is simple, has only one module. But with the scopes and features adding in the project, you may need to separate your project to multiple modules. So hosting the versions in a central place is very necessary.
Other than that, you may have to use the same version numbers of the same library or component group. For example, you may use recyclerview
, v4
, design and app_compat.
If the version numbers are different, you may face some unknown issues when running your project.
Then the question is how to centralize the versions of the libraries. Let’s look at a sample of Google Android Architecture Component: BasicSample.
Google leverages gradle to centralize the version numbers. Let’s see the versions.gradle
file.
ext.deps = [:]
def versions = [:]
versions.android_gradle_plugin = '3.3.1'
versions.apache_commons = "2.5"
versions.arch_core = "2.0.0"
versions.atsl_rules = "1.1.0-alpha4"
versions.atsl_runner = "1.1.0-alpha4"
versions.constraint_layout = "2.0.0-alpha2"
versions.core_ktx = "1.0.0"
versions.dagger = "2.16"
versions.dexmaker = "2.2.0"
versions.espresso = "3.1.0-alpha4"
versions.glide = "4.8.0"
versions.hamcrest = "1.3"
versions.junit = "4.12"
versions.kotlin = "1.3.20"
versions.lifecycle = "2.0.0"
versions.mockito = "2.7.19"
versions.mockito_all = "1.10.19"
versions.mockito_android = "2.22.0"
versions.mockwebserver = "3.8.1"
versions.navigation = "2.0.0-rc02"
versions.okhttp_logging_interceptor = "3.9.0"
versions.paging = "2.1.0-rc01"
versions.retrofit = "2.3.0"
versions.room = "2.1.0-alpha03"
versions.rx_android = "2.0.1"
versions.rxjava2 = "2.1.3"
versions.support = "1.0.0"
versions.timber = "4.5.1"
versions.work = "2.0.0-rc01"def deps = [:]def support = [:]
support.annotations = "androidx.annotation:annotation:$versions.support"
support.app_compat = "androidx.appcompat:appcompat:$versions.support"
support.recyclerview = "androidx.recyclerview:recyclerview:$versions.support"
support.cardview = "androidx.cardview:cardview:$versions.support"
support.design = "com.google.android.material:material:$versions.support"
support.v4 = "androidx.legacy:legacy-support-v4:$versions.support"
support.core_utils = "androidx.legacy:legacy-support-core-utils:$versions.support"
support.core_ktx = "androidx.core:core-ktx:$versions.core_ktx"
deps.support = supportext.deps = deps
What does ext.deps = [:]
mean?
First, let’s look at ext
. ext
is the keyword that could define a global variable. The global variable could be accessed from other gradle files no matter where it is under the same project.
Second, [:]
means creating a new HashMap. If you are familiar with Java, it’s similar to public static Map deps = new HashMap()
.
Then what is def versions = [:]
?
def
use to define the local variable. So it could only be accessed in the same gradle file.
Then look at the usage of versions.support
, all the support libraries use the same version.
How to use the versions.support in another gradle file?
It’s simple, we just need to use deps.versions.support
. What’s the magic behind that? The last line of the sample ext.deps = deps
transmit the deps to a global variable.
To summarize the benefits of this approach:
- Centralize the versions of all dependencies into one file
- Define one version number for each library group, and use everywhere. All libraries in one group are on the same page.
- Easy to track the history of the version change.