Best Way to Include Debug Code?
Asked Answered
P

7

44

I am programming Android applications, and the best way here may or may not be the same as Java in general.

I simply want to be able to set a debug flag that will only execute certain portions of code when it's set to true––equiv to C++ setting a preprocessor #define DEBUG and using #ifdef DEBUG.

Is there an accepted or best way to accomplish this in Java?

Right now I'm just going to set a variable in my Application object, but I don't imagine this is the best way.

Pol answered 27/4, 2010 at 3:43 Comment(1)
Check out this answer: https://mcmap.net/q/366409/-java-preprocessorMadson
O
31

That's the way I do it:

// in some.class.with.Constants
public static final boolean DEV_MODE = true;

// in some other class
import static some.class.with.Constants.DEV_MODE;

if(DEV_MODE){
    Log.d('sometag', 'somemessage');
}
Otoole answered 27/4, 2010 at 5:4 Comment(3)
Nice! I didn't know you could import all the way down to a single constant! I was looking to avoid typing X.X.CONST every time. This, combined with the answer referenced in the comment on my question (https://mcmap.net/q/366409/-java-preprocessor), which shows how an 'if' statement with a false constant in its condition gets excluded from the compilation, is exactly what I was looking for. Thanks!Pol
By my experiments (checking the byte code), this approach will only exclude the code from the class where the constant is defined.. other classes will still have the code in them (it won't execute though). am i wrong?Caution
import static is basically just a name thingCaution
B
56

Instead of using your own flag, you can use the flag set automatically by ADT, like this:

final static int appFlags = context.getApplicationInfo().flags;
final static boolean isDebug = (appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0

The FLAG_DEBUGGABLE bit is automatically set to true or false, depending on the "debuggable" attribute of the application (set in AndroidManifest.xml). The latest version of ADT (version 8) automatically sets this attribute for you when not exporting a signed package.

Thus, you don't have to remember setting / resetting your own custom flag.

You can read more in this thread.

Biotype answered 29/12, 2010 at 15:42 Comment(0)
P
35

I suggest to use inbuilt android API BuildConfig

if (BuildConfig.DEBUG) {
  // do something for a debug build
}
Portland answered 16/3, 2017 at 15:52 Comment(1)
this should be marked at the correct answer or the one below for the correct use of the APis provided by SDKTruncate
O
31

That's the way I do it:

// in some.class.with.Constants
public static final boolean DEV_MODE = true;

// in some other class
import static some.class.with.Constants.DEV_MODE;

if(DEV_MODE){
    Log.d('sometag', 'somemessage');
}
Otoole answered 27/4, 2010 at 5:4 Comment(3)
Nice! I didn't know you could import all the way down to a single constant! I was looking to avoid typing X.X.CONST every time. This, combined with the answer referenced in the comment on my question (https://mcmap.net/q/366409/-java-preprocessor), which shows how an 'if' statement with a false constant in its condition gets excluded from the compilation, is exactly what I was looking for. Thanks!Pol
By my experiments (checking the byte code), this approach will only exclude the code from the class where the constant is defined.. other classes will still have the code in them (it won't execute though). am i wrong?Caution
import static is basically just a name thingCaution
U
27

Revision 17 of SDK tools (March 2012) introduced a way to imitate C's #ifdef DEBUG

From the General Notes:

Added a feature that allows you to run some code only in debug mode. 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.

Ucayali answered 29/3, 2012 at 12:41 Comment(1)
Always returns false for my library that my app is usingRitualism
N
14

This works for me with code if (BuildConfig.DEBUG), using the BuildConfig class. This is a safe and easy code to do. Be careful when using this style of code. Don't use it such that there are 2 different distinct branches of code, between Release and Debug versions. If you do, it might invalidate the app testing for the Release version. For me, I have used it only to skip calling Log messaging.

More details on this class BuildConfig @ Build System Concepts.

Nudi answered 28/7, 2015 at 0:48 Comment(2)
Almost zero CPU usage. Perfect.Reset
@OrB, I am glad for you and I think it's the best choice for the modern Android Studio. I will edit my post since now it should be used as the easiest code to do. Thanks for noticing and giving me a reminder.Nudi
F
8
if ( Debug.isDebuggerConnected() ) {
  // debug stuff
}
Foret answered 27/4, 2010 at 5:29 Comment(3)
I like this, and I imagine I'll find it quite useful at times, but I like how the other approach omits the entire block from the compilation with a false constant in the 'if' statement.Pol
I use both methods and comment conditionals. Each has its place, although a real preprocessor would be best.Foret
Problem with this is, the debugger is not always connected, when my app crashes. I am collecting the stack trace in exception & saving in a file. But I MUST do it in debug build only.Toccaratoccata
A
1

I think that writing tests is better alternative than adding DEBUG code.

My point is that when you write test for some component/method/class you don't pollute your original source code with some redundant debug code.

Arctogaea answered 29/12, 2010 at 15:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.