自定义Android的Log,不用写Tag

本文介绍了一种使用Java调用栈自动获取日志TAG的方法,简化了在每个类中定义TAG的过程,使开发者可以将注意力集中在消息内容上。通过自定义的LogUtils类,实现了在不同日志级别下自动获取类名、文件名、行号及方法名,并将其作为TAG。此外,提供了灵活的日志打印方式,包括是否打印调用栈信息,以及调整当前打印日志的最低等级,便于在开发和发布阶段控制日志输出。

Android的日志默认是带TAG的这种形式,如Log.i(String TAG, String msg),在每个类中都要定义TAG,比较烦,现利用java调用栈获取调用处所在类名,自动将类名作为TAG,避免了每个类写TAG,将重心放到msg上。

具体代码如下:

public class LogUtils {
	private static StackTraceElement[] currentThread;
	private static String tagName;
	private static String msgT;
	private static String msgC;
	private static String callTraceStack;
	private static int curLogLevel = Log.VERBOSE;

	public static int getCurLogLevel() {
		return curLogLevel;
	}
	public static void setCurLogLevel(int curLogLevel) {
		LogUtils.curLogLevel = curLogLevel;
	}
	public synchronized static void initTrace(String msg, int... isPrintStack) {
		int isPrintStackOne = isPrintStack.length > 0 ? isPrintStack[0] : 10;
		currentThread = Thread.currentThread().getStackTrace();
		// vm调用栈中此方法所在index:2:VMStack.java:-2:getThreadStackTrace()<--Thread.java:737:getStackTrace()<--
		int curentIndex = 4;
		String className = currentThread[curentIndex].getFileName();
		int endIndex = className.lastIndexOf(".");
		tagName = endIndex < 0 ? className : className.substring(0, endIndex);
		msgT = "[" + className + ":" + currentThread[curentIndex].getLineNumber() + ":"
				+ currentThread[curentIndex].getMethodName() + "()]---";
		msgC = "msg:[" + msg + "]";
		if (isPrintStackOne > 0) {
			StringBuilder sb = new StringBuilder();
			sb.append("callTraceStack:[");
			for (int i = curentIndex; i < curentIndex + isPrintStackOne && i < currentThread.length; i++) {
				sb.append(currentThread[i].getFileName() + ":" + currentThread[i].getLineNumber() + ":"
						+ currentThread[i].getMethodName() + "()" + "<--");
			}
			sb.append("]");
			callTraceStack = sb.toString();
			msgC += callTraceStack;
		}
	}
	public static void e(String msg, boolean printStack) {
		e(msg, printStack ? 105 : 0);
	}
	public static void w(String msg, boolean printStackNum) {
		w(msg, printStackNum ? 105 : 0);
	}
	public static void d(String msg, boolean printStackNum) {
		d(msg, printStackNum ? 105 : 0);
	}
	public static void v(String msg, boolean printStackNum) {
		v(msg, printStackNum ? 105 : 0);
	}
	public static void i(String msg, boolean printStackNum) {
		i(msg, printStackNum ? 105 : 0);
	}
	public static void e(String msg, int... printStackNum) {
		if (curLogLevel > Log.ERROR) {
			return;
		}
		initTrace(msg, printStackNum.length > 0 ? printStackNum[0] : 0);
		Log.e(tagName, msgT + msgC);
	}
	public static void w(String msg, int... printStackNum) {
		if (curLogLevel > Log.WARN) {
			return;
		}
		initTrace(msg, printStackNum.length > 0 ? printStackNum[0] : 0);
		Log.w(tagName, msgT + msgC);
	}
	public static void d(String msg, int... printStackNum) {
		if (curLogLevel > Log.DEBUG) {
			return;
		}
		initTrace(msg, printStackNum.length > 0 ? printStackNum[0] : 0);
		Log.d(tagName, msgT + msgC);
	}
	public static void v(String msg, int... printStackNum) {
		if (curLogLevel > Log.VERBOSE) {
			return;
		}
		initTrace(msg, printStackNum.length > 0 ? printStackNum[0] : 0);
		Log.v(tagName, msgT + msgC);
	}
	public static void i(String msg, int... printStackNum) {
		if (curLogLevel > Log.INFO) {
			return;
		}
		initTrace(msg, printStackNum.length > 0 ? printStackNum[0] : 0);
		Log.i(tagName, msgT + msgC);
	}
}

说明:
1. 使用方式:LogUtil.v("~test~");
2. public static void v(String msg, int... printStackNum)中printStackNum为可选参数,表示打印多少层调用栈
3. curLogLevel表示当前打印日志的最低等级,比如设置为Log.INFO,则info以上的打印,以下的不打印,这样在Debug阶段,设置为

Log.VERBOSE,在Release阶段设置为Log.ERROR或者Log.ASSERT,就可以不打印哪些调试日志

4. 这样使用Thread.currentThread().getStackTrace(),效率可能比较低,调试可以用,发行版本,最好关闭日志如果有大神有优化方案,不吝指点一二。


Android 中,自定义日志格式通常是指对日志的输出样式、标签、颜色、线程信息、类名、方法名等内容进行个性化定制。这在使用如 [Logger](https://github.com/orhanobut/logger) 这类第三方日志库时非常常见。 --- ### ✅ 使用 Logger 库自定义日志格式的方法 你可以通过实现 `FormatStrategy` 接口或继承 `PrettyFormatStrategy` 来自定义日志格式。 --- ### 示例:自定义日志格式 ```java public class CustomLogFormatStrategy implements FormatStrategy { private final String tag; private CustomLogFormatStrategy(String tag) { this.tag = tag; } @Override public void log(int priority, String onceOnlyTag, String message) { String threadName = Thread.currentThread().getName(); String logMessage = String.format(" [%s] %s", threadName, message); Log.println(priority, tag, logMessage); } public static class Builder { private String tag = "CUSTOM_TAG"; public Builder() {} public Builder tag(String tag) { this.tag = tag; return this; } public FormatStrategy build() { return new CustomLogFormatStrategy(tag); } } } ``` --- ### 使用方式: ```java Logger.addLogAdapter(new AndroidLogAdapter(new CustomLogFormatStrategy.Builder() .tag("MyCustomTag") .build())); ``` 或者: ```java Logger.addLogAdapter(new CustomAndroidLogAdapter()); ``` 其中 `CustomAndroidLogAdapter` 可以继承 `AndroidLogAdapter` 并重 `log()` 方法。 --- ### 示例:继承 AndroidLogAdapter 自定义格式 ```java public class CustomAndroidLogAdapter extends AndroidLogAdapter { public CustomAndroidLogAdapter(@NonNull FormatStrategy formatStrategy) { super(formatStrategy); } @Override public void log(int priority, String tag, String message) { // 可以添加额外处理,如入文件、上传等 super.log(priority, tag, "【自定义前缀】" + message); } } ``` --- ### ✅ 使用场景 - 添加日志时间戳 - 显示类名、方法名、行号 - 区分日志级别颜色(仅在支持的库中) - 在开发环境打印详细日志,生产环境只打印错误日志 - 将日志入文件或上传服务器 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值