Strip out unused code and libraries with Gradle

Sometimes, we want to write code just for debugging purpose, and we don’t want this code to live in our production. Furthermore, we don’t want to include any libraries that we are using just for debug and testing purposes, in our production apk.

A very good example will be Stetho. Stetho is a great library when we want to browse our database very easily, but it also includes a bunch of code and classes (almost 2K methods) that we have no reason to include in our apk file. Of course, we think that proguard supposed to do this, but if our code includes a method from Stetho library, proguard won’t strip the library out from the apk file, and when we want to shrink our apk as much as possible, all this code not helps us.

So we can do this Gradle. By default, in Android Studio, all the code of our application lives under app/src/main/java folder (and the code for tests in androidTest and test folder), But we can have a different code for different flavours of our app. By default, our app will have 2 flavours: release and debug. You can switch this flavours in the left pane of android studio:

 

 

 

By adding folders to your app directory, you can have 2 different classes with the same signature for each flavour: for release flavour, you need app/src/release/java folder, and for debug flavour you need app/src/debug/java folder.

 

 

 

 

 

Now we can put in this folders duplicate classes, and the build system will take the class belongs to the current flavour. Let’s demonstrate it: We want to use Stetho just in debug flavour, so in our Application we can put this line inside the onCreate():

DebugInitials.init(this);

And in the app/src/debug/java folder we will create DebugInitials.class like this:

public class DebugInitials {
    public static void init(Application application){
        //Exists just in debug build
        Stetho.initializeWithDefaults(application);
    }
}

In the app/src/release/java folder we will create DebugInitials.class like this:

public class DebugInitials {
    public static void init(Application application){

    }
}

This way, Stetho code will live just in debug flavour. Now we want to tell gradle to include Stetho library just in debug. This done very easily:

debugCompile 'com.facebook.stetho:stetho:1.4.2'

And that’s it! Stetho won’t be included any more in our production apk.

Create different values for Debug and Release with Gradle

Sometimes it may happen that you want to have different values in your app for debug and release versions. Of course, you can define it in code and change it yourself but this can become tiring, and cause you to make fatal errors when you forget to switch this values properly.

With Gradle you can do this in very elegant way. Let’s say we want to use some BASE_URL with one url address for testing it when we in debug mode, and a different value when we in release mode. We will define it in the build.gradle file:

android {

    buildTypes {
        debug {
            buildConfigField "String", "BASE_URL", "\"http://192.168.0.129:8090/\""
        }

        release {
            buildConfigField "String", "BASE_URL", "\"http://www.thedroidboy.com/\""
            //rest of code
        }
    }
}

Now we can use this value in our code as gradle will produce a class in our package called BuildConfig.class and we can access its values everywhere in our code:

String APP_BASE_URL = BuildConfig.BASE_URL;

The proper values will be injected based on our build type.