Using Gradle for Android Modularisation

With Instant Apps, Google is trying heavily to push people to modularise their apps in Android, so that instant apps (hopefully) take off. Let’s take a look at how we can use Gradle to help us achieve this.

To begin with, we’re just gonna create a new Android project and add the retrofit dependency into our project. Create a new blank application and in the app build.gradle file, inside the dependencies closure, add the following:

Screen Shot 2018-01-02 at 11.15.32.png.png

Now sync, and you should now be able to use retrofit inside this module. Cool. Now imagine you have more modules, and you need the same library over multiple modules. Do we just copy/paste this everywhere we need it? Thankfully, Gradle’s DSL is Groovy (hopefully Kotlin soon), which we can make use of to clean this up.

Here’s how it’ll work: The project’s build.gradle file will contain extension closures which we’ll use to specify our targetSdk, compileSdk, buildTools, etc. In here we’ll also define where the libraries that we want to use in any of our modules are. Finally we’ll add functions that we’ll call in our separate module’s gradle files to actually add the library.

First in your project gradle file, scroll to the allProjects {} function. In here we have a repositories function. Underneath that (but still in allProjects), add the following:

Screen Shot 2018-01-02 at 11.23.20.png.png

In the ext function, we’re just defining some variables that are consistent through the various module’s gradle files. Now head over to your app gradle file and inside the android {} function, where you used to have compileSdkVersion = 26, change this to compileSdkVersion(compileSdk). Same for buildToolsVersion, minSdkVersion, and targetSdkVersion.

Screen Shot 2018-01-02 at 11.26.34.png.png

Re-sync and nothing should have changed. But we can now do this across all our modules. Now let’s take a look at those dependencies.

Head back to the project gradle, and head back into the allProjects {} function. Underneath the ext function that we just added, add a variable to define the retrofit version. Underneath that, add another ext function, defining a new variable ‘retrofit’ which is an array. In the array, add everything that you need for retrofit to work.

Screen Shot 2018-01-02 at 11.30.17.png.png

Now we have a variable will includes everything we need for retrofit. The final thing we need is some way of actually using this variable in our app gradle file. To do this we’ll define a new function that takes one of these variables and for each code in the array, syncs the library. Add the following in the project gradle in the allProjects function, which will allow us to add the library internal to the module.

Screen Shot 2018-01-02 at 11.37.36.png.png

You’ll notice here we check if the code starts with a # or *, and do different things based on them, and if it doesn’t begin with either, we add it through implementation. This is so that we can still add annotation processors and still maintain control. So for example if the thing you’re adding is an annotation processor, instead of: “android.arch.persistence.room:compiler:$lifecycleVer”, which is an annotation processor, just do “*android.arch.persistence.room:compiler:$lifecycleVer”.

Now head back to the app gradle, and at root level, add the following line:

Screen Shot 2018-01-02 at 11.41.58.png.png

Delete everything to do with retrofit from the dependencies function and resync. Fingers crossed, everything will be fine, and you’ll be able to use retrofit within that module. Yay! Now of course, you probably want more than just to be able to add libraries internally to the module, so below are functions to do just that, including for tests.

Now we can add more modules, and more gradle files, and have a single source of truth for our libraries and project settings throughout!

Below are the final app and project gradle files, using test and androidTest functions as well as internalLib.

Project build.gradle

App build.gradle (multiple of these as your split your app into modules)

Next week we’ll be taking a look at how Swift is compiled to machine code. See you then!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s