How to remove all debug logging calls before building the release version of an Android app?
I find a far easier solution is to forget all the if
checks all over the place and just use ProGuard to strip out any Log.d()
or Log.v()
method calls when we call our Ant release
target.
That way, we always have the debug info being output for regular builds and don't have to make any code changes for release builds. ProGuard can also do multiple passes over the bytecode to remove other undesired statements, empty blocks and can automatically inline short methods where appropriate.
For example, here's a very basic ProGuard config for Android:
-dontskipnonpubliclibraryclasses
-dontobfuscate
-forceprocessing
-optimizationpasses 5
-keep class * extends android.app.Activity
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
}
So you would save that to a file, then call ProGuard from Ant, passing in your just-compiled JAR and the Android platform JAR you're using.
See also the examples in the ProGuard manual.
Update (4.5 years later): Nowadays I used Timber for Android logging.
Not only is it a bit nicer than the default Log
implementation — the log tag is set automatically, and it's easy to log formatted strings and exceptions — but you can also specify different logging behaviours at runtime.
In this example, logging statements will only be written to logcat in debug builds of my app:
Timber is set up in my Application
onCreate()
method:
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
}
Then anywhere else in my code I can log easily:
Timber.d("Downloading URL: %s", url);
try {
// ...
} catch (IOException ioe) {
Timber.e(ioe, "Bad things happened!");
}
See the Timber sample app for a more advanced example, where all log statements are sent to logcat during development and, in production, no debug statements are logged, but errors are silently reported to Crashlytics.
How to remove Log.d() calls in release build of an Android app?
Make sure your proguard configuration does not have -dontoptimize
in it. It's the proguard optimizer that removes method calls that have "no side effects".
The SDK default proguard-android.txt
has -dontoptimize
in it. Use proguard-android-optimize.txt
instead, and don't add -dontoptimize
in your project-specific proguard configuration.
Could you please state some source where I could read up on the subject. If it exists of course.
Well, for starters -assumenosideeffects
is listed under optimization options in the documentation.
One more thing bothers is that, I have read that using proguard-android-optimize.txt can cause problems on some devices. So, it is a sort od catch 22 situation.
Proguard in general can have side effects. You need to test your proguard-processed application thoroughly.
If you want to remove logging from release builds without using proguard at all, you can e.g. add
if (BuildConfig.DEBUG)
before every logging call where BuildConfig
is the build configuration generated by the Gradle Android plugin. Since the DEBUG
there is a compile-time constant, the Java compiler sees the condition can never be true on a release configuration and won't emit the bytecode inside the conditional block.
Removing Logging from Production Code in Android?
The IMO best solution is to write code like below wherever you call your logging methods.
if (SOME_LOG_CONSTANT) Log.d(TAG, "event:" + someSlowToEvaluateMethod());
By changing 1 constant you strip away every logging that you don't want. That way the part behind if (false)
should not even get into your .class file since the compiler can completely remove it (it is unreachable code).
This also means that you can exclude whole code blocks from your release software if you wrap them in that if
. That's something even proguard can't do.
the SOME_LOG_CONSTANT
can be BuildConfig.DEBUG
if you use SDK Tools r17 and above. That constant is automatically changed for you depending on build type. Thx @Christopher
Remove all debug logging calls from third-party lib/sdk (Proguard is not working)
ProGuard will only be able to remove logging calls in application code, i.e. code that is being processed and included in your own application. Any logging calls being performed by the Android runtime cannot be removed because the runtime is installed on each device and cannot be modified in advance obviously.
Looking at your rules and gradle file, the setup looks correct and also works for me to remove calls to android.util.Log
. Ensure that you are using a recent version of ProGuard (e.g. 5.2.1 or later). Also you have ProGuard still disabled in your release
buildType, you will need to set minifyEnabled
to true
to enable it.
Is there an easy way to deactivate logging prior to releasing your app on the market?
You can do this through proguard. In the latest SDK and tools a proguard configuration file should already exist. Christopher answered this in a similar question.
The easiest way is probably to run your compiled JAR through ProGuard before deployment, with a config like:
-assumenosideeffects class android.util.Log {
public static int v(...);
}
That will — aside from all the other ProGuard optimisations — remove any verbose log statements directly from the bytecode.
You can decide which logoutputs you want to disable through adding
-assumenosideeffects class android.util.Log {
public static int d(...);
public static int i(...);
public static int e(...);
}
to the proguard config file as well. I like to keep the .e Messages in my code because those are only used in some catch parts want decrease perfomance during the normal execution of the application.
Related Topics
Navigationview Get/Find Header Layout
How to Send a Json Object Over Request With Android
How to Turn on Front Flash Light Programmatically in Android
What Is the List of Supported Languages/Locales on Android
How to Retrieve the Dimensions of a View
How to Get Zoom Functionality For Images
How to Obtain Crash-Data from My Android Application
What Permission Do I Need to Access Internet from an Android Application
How to Change the Background Color of the Actionbar of an Actionbaractivity Using Xml
How to Use the Textwatcher Class in Android
Android Saving File to External Storage
Fling Gesture Detection on Grid Layout
The Application May Be Doing Too Much Work on Its Main Thread
Android "Only the Original Thread That Created a View Hierarchy Can Touch Its Views."