如何在Android上配置java.util.logging?

tan*_*jie 24 logging android

我想在Android上使用java.util.logging.我想使用logging.properties配置日志记录系统.但是如何使用特定的配置文件告诉Android?例如,我将logging.properties放在应用程序的类路径根目录中.Android如何知道logging.properties的位置.

谢谢

小智 55

现在这是我的一个项目的常见问题解答,希望更多人会在这里找到它:java.util.logging在Android上正常工作.请不要在代码中使用任何其他内容,日志框架就像Java世界中的有害生物一样.

破坏的是Android附带的默认日志记录处理程序,它忽略任何级别比INFO更精细的日志消息.你没有看到DEBUG等消息.

原因是在AndroidHandler.java中调用Log.isLoggable():

https://github.com/android/platform_frameworks_base/blob/master/core/java/com/android/internal/logging/AndroidHandler.java

以下是您修复它的方法:

import android.util.Log;
import java.util.logging.*;

/**
 * Make JUL work on Android.
 */
public class AndroidLoggingHandler extends Handler {

    public static void reset(Handler rootHandler) {
        Logger rootLogger = LogManager.getLogManager().getLogger("");
        Handler[] handlers = rootLogger.getHandlers();
        for (Handler handler : handlers) {
            rootLogger.removeHandler(handler);
        }
        rootLogger.addHandler(rootHandler);
    }

    @Override
    public void close() {
    }

    @Override
    public void flush() {
    }

    @Override
    public void publish(LogRecord record) {
        if (!super.isLoggable(record))
            return;

        String name = record.getLoggerName();
        int maxLength = 30;
        String tag = name.length() > maxLength ? name.substring(name.length() - maxLength) : name;

        try {
            int level = getAndroidLevel(record.getLevel());
            Log.println(level, tag, record.getMessage());
            if (record.getThrown() != null) {
                Log.println(level, tag, Log.getStackTraceString(record.getThrown()));
            }
        } catch (RuntimeException e) {
            Log.e("AndroidLoggingHandler", "Error logging message.", e);
        }
    }

    static int getAndroidLevel(Level level) {
        int value = level.intValue();

        if (value >= Level.SEVERE.intValue()) {
            return Log.ERROR;
        } else if (value >= Level.WARNING.intValue()) {
            return Log.WARN;
        } else if (value >= Level.INFO.intValue()) {
            return Log.INFO;
        } else {
            return Log.DEBUG;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在应用程序的主要活动/初始化代码中:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    AndroidLoggingHandler.reset(new AndroidLoggingHandler());
    java.util.logging.Logger.getLogger("my.category").setLevel(Level.FINEST);
...
Run Code Online (Sandbox Code Playgroud)

TL; DR:是的,您可以使用一些魔术属性或adb shell命令,甚至可以了解愚蠢的内置日志记录处理程序如何DalvikLogging.loggerNameToTag将类别名称转换为标记(您必须为这些魔术属性和shell命令执行此操作),但为什么要这么麻烦?记录不够痛苦吗?


Mic*_*yan 5

通常,人们使用android.util.Log在 Android 上进行日志记录。使用该记录器有一些关键优势,例如能够用于adb logcat查看发送到这些日志的日志记录输出。

您可以尝试将logging.properties放入assets/或中res/raw/。如果 Android 没有在那里选择这些,那么可以使用java.util.logging.LogManagerreadConfiguration(java.io.InputStream)强制加载它。(您可以使用 Resources 和 AssetManager 类以 InputStream 形式获取文件)。