Reputation: 10101
For performance wise, some people suggest use the following method, e.g.
public class MyActivity extends Activity {
private static final String TAG = "MyApp";
private static final boolean D = true;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, "MyActivity.onCreate debug message"); }
But this is non-senese when are working on a large project, because when you debug, you need to update many files for the debug
flag, are there any better method?
Upvotes: 2
Views: 7608
Reputation: 15685
An alternative approach, with less code, is to have these stripped out for the final release app using ProGuard.
Basically, in the app\proguard-rules.pro
file, define the methods of the android.util.Log
class that you want stripped out. The following addition to the proguard-rules.pro file will cause the v
(verbose) and d
(debug) methods to be stripped out at build time:
# This tell Proguard to assume Log.v and Log.d have no side effects (even
# though they do since they write to the logs) and thus can be removed
# during optimization:
-assumenosideeffects class android.util.Log {
public static int v(...);
public static int d(...);
}
This avoids the need for if (BuildConfig.DEBUG)
-style checks peppered throughout the code.
Also see: Disable LogCat Output COMPLETELY in release Android app?
Upvotes: 2
Reputation: 2262
I had the same problem recently, and I don't think that stripping off the classes with Proguard is a good idea to disable logs. So I ended up writing a simple drop-in replacement for the standard Android Log class
It allows you to control the log levels. It also gives you a lot of "sugar" for logging multiple values, for log tags and even more, and it all comes with only 200 lines of code available on Maven Central/JCenter.
Upvotes: 1
Reputation: 5375
I strongly recommend what Google guys developed at their open source app iosched. Among other reasons it keeps in mind BuildConfig
and checks to see whether or not a log for the specified tag is loggable at the specified level with isLoggable. It's a must for my projects.
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.apps.iosched.util;
import com.google.android.apps.iosched.BuildConfig;
import android.util.Log;
/**
* Helper methods that make logging more consistent throughout the app.
*/
public class LogUtils {
private static final String LOG_PREFIX = "iosched_";
private static final int LOG_PREFIX_LENGTH = LOG_PREFIX.length();
private static final int MAX_LOG_TAG_LENGTH = 23;
public static String makeLogTag(String str) {
if (str.length() > MAX_LOG_TAG_LENGTH - LOG_PREFIX_LENGTH) {
return LOG_PREFIX + str.substring(0, MAX_LOG_TAG_LENGTH - LOG_PREFIX_LENGTH - 1);
}
return LOG_PREFIX + str;
}
/**
* WARNING: Don't use this when obfuscating class names with Proguard!
*/
public static String makeLogTag(Class cls) {
return makeLogTag(cls.getSimpleName());
}
public static void LOGD(final String tag, String message) {
if (Log.isLoggable(tag, Log.DEBUG)) {
Log.d(tag, message);
}
}
public static void LOGD(final String tag, String message, Throwable cause) {
if (Log.isLoggable(tag, Log.DEBUG)) {
Log.d(tag, message, cause);
}
}
public static void LOGV(final String tag, String message) {
//noinspection PointlessBooleanExpression,ConstantConditions
if (BuildConfig.DEBUG && Log.isLoggable(tag, Log.VERBOSE)) {
Log.v(tag, message);
}
}
public static void LOGV(final String tag, String message, Throwable cause) {
//noinspection PointlessBooleanExpression,ConstantConditions
if (BuildConfig.DEBUG && Log.isLoggable(tag, Log.VERBOSE)) {
Log.v(tag, message, cause);
}
}
public static void LOGI(final String tag, String message) {
Log.i(tag, message);
}
public static void LOGI(final String tag, String message, Throwable cause) {
Log.i(tag, message, cause);
}
public static void LOGW(final String tag, String message) {
Log.w(tag, message);
}
public static void LOGW(final String tag, String message, Throwable cause) {
Log.w(tag, message, cause);
}
public static void LOGE(final String tag, String message) {
Log.e(tag, message);
}
public static void LOGE(final String tag, String message, Throwable cause) {
Log.e(tag, message, cause);
}
private LogUtils() {
}
}
Upvotes: 4
Reputation: 938
Another solution is found in one of the answers to this somewhat related question. You can override the Log class like this:
public class Log {
static final boolean LOG = false;
public static void i(String tag, String string) {
if (LOG) android.util.Log.i(tag, string);
}
public static void e(String tag, String string) {
if (LOG) android.util.Log.e(tag, string);
}
public static void d(String tag, String string) {
if (LOG) android.util.Log.d(tag, string);
}
public static void v(String tag, String string) {
if (LOG) android.util.Log.v(tag, string);
}
public static void w(String tag, String string) {
if (LOG) android.util.Log.w(tag, string);
}
}
This way, you don't need the if statement every time you use log. Just change the boolean in your overridden Log class. When you're ready to publish, you can use a tool like ProGuard to strip all the references to Log for performance.
Upvotes: 3
Reputation: 12813
You can check the DEBUG boolean in your BuildConfig:
if (BuildConfig.DEBUG) {
// Do what you need
}
Or else, you can have a debug variable, but instead or keeping it in every activity, declare it in you Application class, and check it's value whenever you need.
If your purpose of that variable is for logging, is a good practice to wrap your loggings into another class, which checks the DEBUG variable:
public class LogUtils {
public static void LOGD(final String tag, String message) {
if (BuildConfig.DEBUG) {
Log.d(tag, message);
}
}
public static void LOGV(final String tag, String message) {
if (BuildConfig.DEBUG) {
Log.v(tag, message);
}
}
public static void LOGI(final String tag, String message) {
if (BuildConfig.DEBUG) {
Log.i(tag, message);
}
}
public static void LOGW(final String tag, String message) {
if (BuildConfig.DEBUG) {
Log.w(tag, message);
}
}
public static void LOGE(final String tag, String message) {
if (BuildConfig.DEBUG) {
Log.e(tag, message);
}
}
}
Then, make log calls to this class:
LogUtils.LOGD(TAG, "MyActivity.onCreate debug message");
Upvotes: 6
Reputation: 40193
I've written a LogWrapper
class which is simple and looks something like this:
public class LogWrapper {
private static final String DEBUG_TAG = "some-tag"
private static boolean logsEnabled;
public static void e(String msg) {
if (logsEnabled) {
Log.e(DEBUG_TAG, msg);
}
}
// other Log methods
}
You can use it instead of Log class, modifying the boolean variable as you wish in one place. Hope this helps.
Upvotes: 1