Be Careful With BuildConfig.DEBUG

In recent versions of the Android Developer Tools (ADT) for Eclipse, there’s a class called BuildConfig which is automatically generated by the build. This class is updated automatically by Android’s build system (like the R class), and it contains a static final boolean called DEBUG, which is normally set to true.

The purpose of BuildConfig.DEBUG

This new flag is intended to be used as a check for debug-only functions. For example, you can use it to control logging, like below:

if (BuildConfig.DEBUG) {
    Log.v(TAG, "onCreate()");
}

You might also use it to control other features, such as whether to enable internal verifications, add test devices for your ads or only show real ads, etc….

The idea behind this flag is that when you are debugging with Eclipse, the flag will be set to true, and when you export a signed release build, the flag will be set to false, thus turning off and on debug features automatically, without you having to remember to toggle a flag.

This would be nice if it actually worked reliably!

The problem with BuildConfig.DEBUG

The problem is that it can be quite dangerous to rely on BuildConfig.DEBUG and ADT to do the right thing, because there are bugs in the build system that cause exported signed release builds to be built with BuildConfig.DEBUG set to true!

Imagine building a release and thinking that your logs and other debug features are turned off, and later realizing that the flag was never set to false. :)

The solution

Although there are workarounds and supposed fixes, I don’t want to have to worry about whether or not it actually worked, and whether all of the debug code actually did get stripped out or not.  Instead, I define my own constant, such as follows:

public class AppConfig {
    public static final boolean DEBUG = false;
}

I’ll use this flag like this:

if (AppConfig.DEBUG) {
    Log.v(TAG, "onCreate()");
}

In conjunction with ProGuard, this works to remove the debug code from the release build 100% of the time. I keep the flag commited to the source tree as false, and override it to true if I need to debug.

This might be a bit of extra work, but I have peace of mind knowing that it will work every single time.

Further reading

Tags: , ,

6 Responses to “Be Careful With BuildConfig.DEBUG”

  1. someone April 14, 2013 at 7:49 pm #

    what would you put in the proguard file in order to make the flag become false?

    • Kevin April 17, 2013 at 1:56 am #

      I solved this by using my own boolean flag — I don’t trust the ADT to do the right thing. ;)

      • Kevin April 17, 2013 at 1:58 am #

        Hmm, if you are referring to this: “In conjunction with ProGuard, this works to remove the debug code from the release build 100% of the time.”

        What I mean is that if you set the flag to false, then Proguard’s shrinking pass should remove the “dead” code from your code base. So, you don’t need to do anything special other than enabling Proguard AFAIK.

  2. shinete July 24, 2013 at 3:41 am #

    That a good way to do. Only one thing that I worried, If I forget to set back DEBUG to false. May cause a huge problem.

    Thanks.

  3. Kisiel September 13, 2014 at 11:41 am #

    In gradle builds you can define custom fields for BuildConfig that depends on build type:

    buildTypes {
    debug {
    buildConfigField “boolean”, “DEBUG_MODE”, “true”
    }
    release {
    buildConfigField “boolean”, “DEBUG_MODE”, “false”
    }
    }

    Gradle creates BuildConfig.DEBUG_MODE flag and you can be sure what value is set in which build.

Trackbacks/Pingbacks

  1. [android] isDebug | PipisCrew Official Homepage - February 17, 2014

    […] SDK Tools, Revision 17 (March 2012) writes : Builds now generate a class called BuildConfig containing a DEBUG constant that is automatically set according to your build type. You can check the (BuildConfig.DEBUG) constant in your code to run debug-only functions. A user writes […]

Leave a Reply