1

出于性能方面的考虑,有些人建议使用以下方法,例如

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标志更新很多文件,有没有更好的方法?

4

6 回答 6

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");
于 2012-07-22T17:10:16.420 回答
4

我强烈推荐谷歌人在他们的开源应用程序 iosched 上开发的东西。除其他原因外,它还牢记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() {
    }
}
于 2014-01-29T09:47:06.747 回答
3

在这个有点相关的问题的答案之一中找到了另一种解决方案。您可以像这样覆盖 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);
    }
}

这样,每次使用 log 时都不需要 if 语句。只需更改覆盖的 Log 类中的布尔值。当您准备好发布时,您可以使用 ProGuard 之类的工具去除对 Log 的所有引用以提高性能。

于 2012-07-22T17:18:03.320 回答
2

使用 ProGuard 去除 Log.v 和 Log.d 消息

另一种使用更少代码的替代方法是使用ProGuard将这些内容剥离出来以用于最终发布的应用程序。

基本上,在app\proguard-rules.pro文件中,定义android.util.Log您想要剥离的类的方法。proguard-rules.pro 文件中的以下添加将导致v(verbose) 和d(debug) 方法在构建时被剥离:

# 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)贯穿整个代码的 -style 检查的需要。

另请参阅:在发布的 Android 应用程序中完全禁用 LogCat 输出?

于 2014-09-30T17:38:02.403 回答
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 类,在一个地方根据需要修改布尔变量。希望这可以帮助。

于 2012-07-22T17:15:44.290 回答
1

我最近遇到了同样的问题,我认为使用 Proguard 剥离类并不是禁用日志的好主意。所以我最终为标准的 Android Log 类编写了一个简单的替代品

https://github.com/zserge/log

它允许您控制日志级别。它还为您提供了很多“糖”来记录多个值、日志标签等等,而且在 Maven Central/JCenter 上只有 200 行代码可用。

于 2015-06-14T12:10:50.700 回答