Determine if a build is debug or release

Hello, I am trying to find out if a build is a debug or release build, programmatically.

My app is made up of several modules, one of which is a commons module. In this module is the BaseActivity class, that I wish to change.

Therefore, I have this as my check for the type of build, with BuildConfig imported as my commons package’s BuildConfig. Among others, it has this:

public static final boolean DEBUG = Boolean.parseBoolean("true");

I am checking this variable to see if it’s a debug build, but, surprisingly, it return “false” (not sure how). I read about a potential gradle bug, so I said “ok, let’s try another way”. So I checked for this:

public static final String BUILD_TYPE = "debug";

In my base activity’s onCreate() method, I have:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (BuildConfig.BUILD_TYPE.equals("debug")) LocalBroadcastManager.getInstance(this).registerReceiver(onQaError, IntentFilter(QA_ERROR_INTENT_ACTION))
}

The condition returns true, but the code that belongs to the if clause does not execute (I even put it in between curly braces, just to be sure).

I even put a boolean in my build.gradle(commons) file, for debug builds, to use that, and that doesn’t work, either. It does work if I put “if(true)”, though.

Can you see what’s going on in here? I am stuck.

You might try fully-qualifying the BuildConfig that you want, to ensure you are referencing it and not one of the other BuildConfig versions. Or, consider using an import alias, since you are using Kotlin. My best guess is that you are somehow referencing the wrong BuildConfig.

Well, no, I checked that the correct BuildConfig is imported. Additionally, if you CTRL+click on the variable, it gets you to the correct BuildConfig.

Then, I’m sorry, but I don’t have any idea why you are getting the results that you are. I have not attempted to reference BuildConfig between modules.

I created a variable:

isDebuggable = BuildConfig.BUILD_TYPE.equals("debug")

In the debugger, I set a breakpoint on this line. I alt-clicked on BuildConfig.BUILD_TYPE.equals("debug"), which evaluates to true. Then, the isDebuggable variable is set to false.

How is this possible? I have never seen anything like this in my life.

Create a scrap project, with just the default app module. Try your BuildConfig experiment there. BuildConfig.DEBUG should work as expected. Then, add a second module to that scrap project. Try your BuildConfig experiment with code in that second module, examining the second module’s BuildConfig. Then expand your experiment to try cross-module BuildConfig references.

There are three main possibilities from this set of experiments:

  1. BuildConfig is not working for you even in a single-module project. Since BuildConfig works for others, we would need to investigate your testing methods.
  2. BuildConfig works fine for the single-module scenario but breaks during the later experiments. Now you know where multi-module BuildConfig starts misbehaving.
  3. All the experiments work fine. Then, the problem is more likely to be something specific to your real project, and we would need to devise further experiments to try to have the scrap project bear closer resemblance to your real project.

To be completely honest, though, cross-module BuildConfig access to me is scary. BuildConfig is designed for internal use; it is not really an API. So, another approach to all of this is seeing how you can avoid having one module depend upon another module’s BuildConfig.

Unless the call points to a totally different place than the one that Android Studio goes to when I perform ctrl+click on the method call, I see no way that this is false. And, remember, the commons module has its own Build variant, and it is that which I interogate - I don’t do cross-module interogations. I simply ask the BuildConfig of the same module “which variant are you?”.

The thing that baffles me is that the right side of the equals is true, and the left side is false. This is irrespective of anything - that’s just a simple declaration. How that is possible is beyond me.

How can this expression:

public static final boolean DEBUG = Boolean.parseBoolean("true");

return false?

OK, here is a revised suggestion:

Create a scrap project, with just the default app module. Try your BuildConfig experiment there. BuildConfig.DEBUG should work as expected.

At this point, either:

  • BuildConfig.DEBUG did work as expected in the scrap project. In that case, you will need to try to determine what is different about your real project that is breaking your BuildConfig expectation.
  • BuildConfig.DEBUG did not work as expected in the scrap project. In that case, something is messed up in your environment (pre-release Android Studio?).

It can’t. Presumably, what you are running is not that code.

For example, in a client’s project that I am helping on, they decided to add in applicationIdSuffix for the debug build type. This was after having shipped the app for a few months and done development on the app for a year. So, for older tagged builds, a debug build would have an application ID like foo.bar, and on the current master branch, it has an application ID like foo.bar.debug. Every time that I switch between branches, I need to do “Sync Project with Gradle Files”. Otherwise, Android Studio 3.6.2 will launch the app with the previous branch’s application ID, not the current branch’s one, if the application ID changed between those branches. It drives me nuts, because if I forget, I make changes in the IDE, run it, and the changes don’t show up… because Studio’s run configurations are out of date from what Gradle now calls for, and Studio launched the other application ID’s version of the app, not the application ID that I am working on now.

My more general point is: BuildConfig works. Most likely, your problem stems from some combination of project setup and build environment (Android Gradle Plugin version, Studio version, etc.). I do not have a silver bullet for you that will fix that problem. At most, I can make some recommendations for experiments to run, in hopes that they might eventually lead you to discover what is going on.

1 Like

I put the same thing,

boolean isDebuggable = BuildConfig.DEBUG

but in my onCreate() method in the MyApplication class. There, BuildConfig.DEBUG returns true, just like in the commons module, but this time the value is indeed assigned to isDebuggable, which does become true. I let the app run further and at the next breakpoint I evaluated BuildConfig.DEBUG for the common module which, despite being declared like this (assuming it’s not actually pointing somewhere else):

public static final boolean DEBUG = Boolean.parseBoolean("true");

returned false^^^

So… it seems that this works for the app module but does not work for the common module.