Logging with Logger under Android

2019-07-03 22:48发布

I've noticed that the following works on PC but not inside the Android simulator.

Logger logger = Logger.getLogger("foo");
logger.log(Level.INFO, "Number is: {0}", new Object[]{new Integer(42)});

It just prints

Number is: {0}

Why does this fail for android?

3条回答
女痞
2楼-- · 2019-07-03 23:26

I found a solution in a roundabout way. Ultimately, I think there is a Formatter somewhere in the default android logging implementation which is rendering just the message, ignoring the params. You should be able to use the Logging API to install a formatter of your own design.

I had already installed a new Handler for a totally separate reason. The source I used is available here: http://4thline.org/projects/download/misc/

The handler is in the teleal-common-1.0.14-source.tar.gz archive. Follow the path to src\main\java\org\fourthline\android\util\FixedAndroidHandler.java.

This site also provides code to install this handler, but it's in a different archive: sash-1.0-SNAPSHOT.tar.gz. Locate 1.0\src\main\java\org\teleal\common\logging\LoggingUtil.java.

You can install this handler by making this call somewhere in your app startup code:

LoggingUtil.resetRootHandler(new FixedAndroidHandler());

What I found was that the Formatter for this Handler is embedded as an anonymous class inside the Handler. How convenient. I could see that the Formatter did not process the parameters passed in via the LogRecord. I just added an "else-if" condition:

private static final Formatter THE_FORMATTER = new Formatter() {
    @Override
    public String format(LogRecord r) {
        String msg = r.getMessage();
        Object[] params = r.getParameters();
        Throwable thrown = r.getThrown();
        if (thrown != null) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            sw.write(r.getMessage());
            sw.write("\n");
            thrown.printStackTrace(pw);
            pw.flush();
            return sw.toString();
        } else if ((params != null) && (params.length > 0) && (msg.indexOf("{0") >= 0)) {
            return MessageFormat.format(msg, params);
        } else {
            return r.getMessage();
        }
    }
};

The if test is consistent with other log formatting code I've seen. In theory you should be able to take a more direct approach of installing a similar Formatter to an existing Handler. I haven't tried this myself due to the fact that the above solution is working for me.

查看更多
爷的心禁止访问
3楼-- · 2019-07-03 23:31

You can accomplish the same String formatting using the static String.format(String format, Object... args) method:

Log.d(TAG, String.format("Number is: %d", new Integer(42)));
查看更多
We Are One
4楼-- · 2019-07-03 23:43

Use:

android.util.Log.i(TAG,  "Number is: " + number);

See http://developer.android.com/reference/android/util/Log.html

查看更多
登录 后发表回答