Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Gradle exclude classes for Debug BuildType

Bakground

I am using Google Play Services in my project for various reasons. Google Play Services are a big dependancy which is drastically increases my build time. So I would like to disable Google Play Services for my "Debug" version , so I could compile my project faster.

What I do ?

To exclude Google Play Services during my debug builds , I just do the conditional compilation like this :

releaseCompile 'com.google.android.gms:play-services-plus:7.5.+'
releaseCompile 'com.google.android.gms:play-services-ads:7.5.+'
releaseCompile 'com.google.android.gms:play-services-gcm:7.5.+'

So Google Play Services are being compiled only for release builds , and not included in Debug builds.So far so good.

A pitfall

There are some classes in my code that are dependent on Google Play Services.I can easily abstract them with interfaces , and load stubs instead.But the problem is , those classes are still being compiled during my "Debug" build even though I am not referencing them directly (in fact I am loading them using reflection).

Workaround

To ignore compilation errors for classes I am not using ,I just exclude them from source sets in debug build type like this :

   debug {
        minifyEnabled false
        sourceSets {
            main {
                java {
                    exclude '**/tracking/impl/**'
                    exclude '**/GoogleApiClientWrapper.java'
                }
            }
        }
    }

And the problem is solved , I am able to compile by "Debug" version without Google play services and the build time is faster.

The problem

Even though I am specifying the sourceSets block only in the "Debug" build type , I have noticed that those classes are stripped anyway even in release build Types. Why ? How can I exclude those classes ONLY for Debug build type ?

NOTE

  • Already configured proguard-rules to not strip those classes (since I am using reflection)
  • Disabled proguard for release build
  • Tried to define source sets in different places (even in flavors) , it looks like the latest sourceSet defined overrides all the previous.
like image 612
Ivelius Avatar asked Oct 21 '25 06:10

Ivelius


1 Answers

If you want to have Java classes that are unique to some build type or product flavor, put them in a sourceset for that build type or product flavor.

If you have a typical Gradle for Android project structure, somewhere, you have src/main/java/, with Java classes in there in appropriate directories based upon package name. Those classes, being in the main sourceset, are used for all builds.

If you want to have classes are are only used in a release build, create a src/release/java/ directory, and move those classes from src/main/java/ to src/release/java/.

In a debug build, the release classes are ignored. In a release build, the release classes are used.

Note that you cannot use this technique to replace classes in main. So, you cannot have com.ivelius.awesomeapp.Foo in main and another com.ivelius.awesomeapp.Foo in release — you will get some form of "duplicate class" error.

like image 77
CommonsWare Avatar answered Oct 23 '25 20:10

CommonsWare



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!