Written by Jacek Kwiecień
Android Developer
Published April 1, 2016

Setup Gradle for your Android project like a boss – part 2

Gradle is a native build system supported by Android StudioIn the previous post I covered some basics and then focused on generating version code and name, which was especially helpful while building apk. Time to move on to the other fancy tricks.

Shared dependency version

Some libraries are meant to be split into modules. Usually, if we use couple of them, we should use all the modules in the same version. An example of such approach could be Google Play Services, AppCompat and design libraries or Retrofit. You should ensure that you’re using the same version of those library modules, otherwise you’ll get in trouble. There is a trick that will help you maintain that.

In the project build.gradle define section like this:

ext {
    supportLibraryVersion = '23.1.1'
    playServicesVersion = '8.3.0'
    retrofitVersion = '2.0.0-beta4'
}

“ext” is not an obligatory name. It’s just a name of the section I came up with. You could use any. Define this section in the root of project’s build. gradle.

Now in your app build. gradle you could add your dependencies like this:

compile "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion"
compile "com.android.support:design:$rootProject.ext.supportLibraryVersion"
compile "com.android.support:cardview-v7:$rootProject.ext.supportLibraryVersion"
compile "com.android.support:recyclerview-v7:$rootProject.ext.supportLibraryVersion"
compile "com.google.android.gms:play-services-plus:$rootProject.ext.playServicesVersion"
compile "com.google.android.gms:play-services-location:$rootProject.ext.playServicesVersion"
compile "com.google.android.gms:play-services-gcm:$rootProject.ext.playServicesVersion"
compile "com.squareup.retrofit2:retrofit:$rootProject.ext.retrofitVersion"
compile "com.squareup.retrofit2:adapter-rxjava:$rootProject.ext.retrofitVersion"
compile "com.squareup.retrofit2:converter-gson:$rootProject.ext.retrofitVersion"

That’s it. Simple, right? Now you can easily change your library versions without missing any and getting yourself in troubles.

SDK and build tools

The same way we just defined shared library versions we could setup values like:

  • compileSdkVersion
  • buildToolsVersion
  • minSdkVersion
  • targetSdkVersion

Just add them to the ext section we defined earlier in the project’s build.gradle:

ext {
    compileSdkVersion = 23
    buildToolsVersion = "23.0.1"
    minSdkVersion = 16
    targetSdkVersion = 23
}

Then use it in your app’s build.gradle:

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode getAutoVersionCode()
        versionName getAutoVersionName()
    }
}

 

Flavors

Flavors are a useful way to differentiate built types. You could use separate flavor if there is production and stage (dev) backend available. Right now I’m gonna assume you already know what the flavors are and skip the basics. Let’s take the example with an URL to production and stage API. Instead doing some conditions in the code you setup buildConfig field in your app build.gradle. Let’s have a look at some example of flavors:

    productFlavors {
        prod {
            applicationId = "com.jacek.myapp"
            buildConfigField "String", "API_URL", "\"http://myapp/api/\""

        }
        stage {
            applicationId = "com.jacek.myapp.stage"
            buildConfigField "String", "API_URL", "\"http://stage.myapp/api/\""
        }
    }

applicationId
You should specify that. This way your prod and stage app could exist on the device in parallel not overwriting themselves.

buildConfigField
It can be some simple constant that you want to access from java code like:

BuildConfig.SERVER_URL

It’s enclosed with escaped “, otherwise currently it might not be treated as a String later. You could make numeric fields without them though. You can now use this String field to send requests to the api.

Shared BuildConfig fields

If for some reason you want to have a buildConfig field that has the same value for every flavor, you don’t have to keep it in each of it. You could do it like this:

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 23
        versionCode getAutoVersionCode()
        versionName getAutoVersionName()

        buildConfigField "boolean", "MONITOR_CRASHES", "true"
        buildConfigField "int", "DEFAULT_PAGE_SIZE", "10"
        buildConfigField "String", "SOME_SHARED_KEY", "\"sdfsdfjejj211e#!\""
    }

 

Conclusion

With all the pros and cons of Gradle, I’d vote for it. Surely the cases presented here are not everything you could do to improve your work process.

You know some other cool use cases? Don’t hesitate to share it in the comments section. I’d love to see them all!

Written by Jacek Kwiecień
Android Developer
Published April 1, 2016