经常会为log定位而烦恼。比如:同一个类,一样的log输出,无法定位到Log输出的行。
通过java StackTraceElement获取类名,以及log输出行
-
- @NonNull
- private static String getSourcePoint()
- {
- final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
- assert stackTrace.length > CALL_STACK_INDEX : "Synthetic stacktrace doesn't have enough elements";
-
- final StackTraceElement st = stackTrace[CALL_STACK_INDEX];
- StringBuilder sb = new StringBuilder(80);
- final String fileName = st.getFileName();
- if (fileName != null)
- {
- sb.append(fileName);
- final int lineNumber = st.getLineNumber();
- if (lineNumber >= 0)
- sb.append(':').append(lineNumber);
- sb.append(' ');
- }
- sb.append(st.getMethodName()).append("()");
- return sb.toString();
- }
- package com.app.test.util.log;
-
- import android.util.Log;
-
- import androidx.annotation.Keep;
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import com.app.test.BuildConfig;
- import net.jcip.annotations.ThreadSafe;
-
-
- @ThreadSafe
- public final class Logger
- {
- private static final String TAG = Logger.class.getSimpleName();
- private static final String CORE_TAG = "APP";
- private static final String FILENAME = "app.log";
-
- public static void v(String tag)
- {
- log(Log.VERBOSE, tag, "", null);
- }
-
- public static void v(String tag, String msg)
- {
- log(Log.VERBOSE, tag, msg, null);
- }
-
- public static void v(String tag, String msg, Throwable tr)
- {
- log(Log.VERBOSE, tag, msg, tr);
- }
-
- public static void d(String tag)
- {
- log(Log.DEBUG, tag, "", null);
- }
-
- public static void d(String tag, String msg)
- {
- log(Log.DEBUG, tag, msg, null);
- }
-
- public static void d(String tag, String msg, Throwable tr)
- {
- log(Log.DEBUG, tag, msg, tr);
- }
-
- public static void i(String tag)
- {
- log(Log.INFO, tag, "", null);
- }
-
- public static void i(String tag, String msg)
- {
- log(Log.INFO, tag, msg, null);
- }
-
- public static void i(String tag, String msg, Throwable tr)
- {
- log(Log.INFO, tag, msg, tr);
- }
-
- public static void w(String tag, String msg)
- {
- log(Log.WARN, tag, msg, null);
- }
-
- public static void w(String tag, String msg, Throwable tr)
- {
- log(Log.WARN, tag, msg, tr);
- }
-
- public static void e(String tag, String msg)
- {
- log(Log.ERROR, tag, msg, null);
- }
-
- public static void e(String tag, String msg, Throwable tr)
- {
- log(Log.ERROR, tag, msg, tr);
- }
-
- // Index of stacktrace depth where the original log method call resides.
- private static final int CALL_STACK_INDEX = 3;
-
- @NonNull
- private static String getSourcePoint()
- {
- final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
- assert stackTrace.length > CALL_STACK_INDEX : "Synthetic stacktrace doesn't have enough elements";
-
- final StackTraceElement st = stackTrace[CALL_STACK_INDEX];
- StringBuilder sb = new StringBuilder(80);
- final String fileName = st.getFileName();
- if (fileName != null)
- {
- sb.append(fileName);
- final int lineNumber = st.getLineNumber();
- if (lineNumber >= 0)
- sb.append(':').append(lineNumber);
- sb.append(' ');
- }
- sb.append(st.getMethodName()).append("()");
- return sb.toString();
- }
-
- // Also called from JNI to proxy native code logging (with tag == null).
- @Keep
- private static void log(int level, @Nullable String tag, @NonNull String msg, @Nullable Throwable tr)
- {
-
- if (BuildConfig.DEBUG || level >= Log.INFO)
- {
- final StringBuilder sb = new StringBuilder(180);
- // Add source point info for file logging, debug builds and ERRORs if its not from core.
- if (tag != null && (BuildConfig.DEBUG || level == Log.ERROR))
- sb.append(getSourcePoint()).append(": ");
- sb.append(msg);
- if (tr != null)
- sb.append('\n').append(Log.getStackTraceString(tr));
- if (tag == null)
- tag = CORE_TAG;
-
- if (logsFolder == null || BuildConfig.DEBUG)
- Log.println(level, tag, sb.toString());
-
- }
- }
-
- private static char getLevelChar(int level)
- {
- switch (level)
- {
- case Log.VERBOSE:
- return 'V';
- case Log.DEBUG:
- return 'D';
- case Log.INFO:
- return 'I';
- case Log.WARN:
- return 'W';
- case Log.ERROR:
- return 'E';
- }
- assert false : "Unknown log level " + level;
- return '_';
- }
- }

如上图,可以看到log输出java的类名,以及行。
略