出于性能方面的考虑,有些人建议使用以下方法,例如
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"); }
但是在处理大型项目时这是非精明的,因为在调试时,您需要为debug
标志更新许多文件,有没有更好的方法?
答案 0 :(得分:6)
您可以在BuildConfig中检查DEBUG布尔值:
if (BuildConfig.DEBUG) {
// Do what you need
}
否则,您可以拥有一个调试变量,但是将其保存在每个活动中,在Application类中声明它,并在需要时检查它的值。
如果您对该变量的目的是用于日志记录,最好将您的日志包装到另一个类中,该类检查DEBUG变量:
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);
}
}
}
然后,对此类进行日志调用:
LogUtils.LOGD(TAG, "MyActivity.onCreate debug message");
答案 1 :(得分:4)
我强烈推荐Google员工在其开源应用程序中开发的内容。在其他原因中,请记住BuildConfig
,并检查指定标记的日志是否可以使用isLoggable在指定级别进行记录。这对我的项目来说是必须的。
/*
* 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() {
}
}
答案 2 :(得分:3)
另一个解决方案是this某个相关问题的答案之一。您可以像这样覆盖Log类:
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);
}
}
这样,每次使用日志时都不需要if语句。只需更改重写的Log类中的布尔值即可。当您准备发布时,可以使用ProGuard之类的工具去除对Log的所有引用以获得性能。
答案 3 :(得分:2)
使用ProGuard的替代方法是使用Disable LogCat Output COMPLETELY in release Android app?删除最终版本的应用程序。
基本上,在app\proguard-rules.pro
文件中,定义要删除的android.util.Log
类的方法。对proguard-rules.pro文件的以下添加将导致在构建时删除v
(详细)和d
(调试)方法:
# 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(...);
}
这样可以避免在整个代码中使用if (BuildConfig.DEBUG)
样式检查。
另见:{{3}}
答案 4 :(得分:1)
我写了一个LogWrapper
类很简单,看起来像这样:
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
}
您可以使用它而不是Log类,在一个地方根据需要修改布尔变量。希望这会有所帮助。
答案 5 :(得分:1)
我最近遇到了同样的问题,我不认为用Proguard剥离课程是禁用日志的好主意。所以我最终为标准的Android Log类编写了一个简单的替代品
它允许您控制日志级别。它还为你提供了很多糖#34;用于记录多个值,用于记录标记甚至更多,并且在Maven Central / JCenter上只提供了200行代码。