I'm using Jack's Wharton Hugo Library and AndroidDevMetrics plugins to measure method execution time and application performance in Android. I need to make those libraries compile only in debug build and to exclude them from release builds.
Because both of those library applied only using the plugin syntax:
apply plugin: 'com.frogermcs.androiddevmetrics'
apply plugin: 'com.jakewharton.hugo'
and do not require any dependencies in the Gradle file I can't exclude them using the testCompile option. The only way supplied to control Hugo is setting this in the gradle file:
hugo {
enabled false
}
while the only way to control AndroidDevMetrics is:
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//Use it only in debug builds
if (BuildConfig.DEBUG) {
AndroidDevMetrics.initWith(this);
}
}
}
The question: Those control options do not prevent from those library files from being complied to the release version of the application. I'm looking for a way to exclude those plugins in Gradle in case I build a release version.
You can use a combination of Proguard and Sourcesets to ensure that libraries aren't compiled into your release application, and gradle properties to apply plugins conditionally.
You can conditionally include a gradle plugin by declaring it as you normally would at the top of your build.gradle, and surrounding it with a conditional clause. For example, the code below checks whether a property exists, and if it does, applies the plugin.
if (hasProperty('shouldApplyDevMetrics')) {
println "Applying devmetrics plugin"
apply plugin: 'com.frogermcs.androiddevmetrics'
}
else {
println "Not applying devmetrics plugin in release build"
}
To include a property, you can use the command line flag below when invoking gradle. You can create similar launch configurations if you wish to use Android Studio.
./gradlew assembleDebug -PshouldApplyDevMetrics=true
This removes the gradle plugin from the release build, but depending on the library, may leave compiled code in your app. You can address this using one of the two methods detailed below.
The first (and simplest) approach to completely removing a library from an APK is to strip out all the relevant code using the Proguard tool. You should update your release buildType to enable proguard, and load a custom rules file.
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
By default, this should strip out the annotations. It's possible that you will need to update your proguard configuration for other dependencies which rely on reflection or annotations. If enabling proguard produces compiler warnings relating to Hugo, you can disable them by adding the following line:
-dontwarn hugo.weaving**
This approach does mean that you need to keep the dependency in your build.gradle file, but is the best approach for something like Hugo, which is used all over the place by adding annotations.
To remove the AndroidDevMetrics library from the release build entirely, we should start off by creating a debug and release sourceset, then add a functional class under src/debug, and a no-op class under src/release.
// src/debug
public class DevMetricWrapper() {
void doMetricsThings(Context context) {
AndroidDevMetrics.initWith(context);
}
}
// src/release
public class DevMetricWrapper() {
void doMetricsThings(Context context) {
// no-op
}
}
You can then alter the build.gradle file for your module so that the library is only included as a debug dependency:
debugCompile 'com.example.yourlibrary'
Please note that if you're planning on doing anything more complicated, Dagger is a very useful library as it allows you to inject different dependencies depending on what flavor you are building.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With