思路:
- 获取当前线程的StackTraceElement的集合;
- 判断出调用log的类;
- 获取这个类的StackTraceElement。
实践
- 获取最后调用我们log的StackTraceElement,这里的 tag 我们使用的是 类名,如果你的tag,不是类名则不能使用这个方法获取目标stack trace element。
// 获取最后调用我们log的StackTraceElement
private static StackTraceElement getTargetStack(String tag) {
// 用于存储 目标类 中所有调用的方法
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
// 只获取目标类中的 element
if (element.getClassName().contains(tag)) {
return element;
}
}
// 获取不到返回 null
return null;
}
查看stacktrace 中的方法,很简单我就不解释了。
这个位置只有写成固定格式
"("+fileName+":"+lineNumber+")"
,才能实现定位功能。
...
/**
* @param tag 目标类的 SimpleName
*/
StackTraceElement targetStack = getTargetStack(tag);
if (null == targetStack) {
return;
}
String location = "Location .(" + targetStack.getFileName() + ":" + targetStack.getLineNumber() + ")";
- 最后打印出的log,如下图:
全部代码
package com.zhouzhouwang88.oa_helper.utils;
import android.util.Log;
/**
* Author: zhangjianlong
* Date: 2017/6/20
* E-Mail:m13478943650@163.com
* Desc:
*/
public class LogUtils {
public static String TAG = "LogUtils";
private static final boolean DEBUG = true;
private static final int D = 745;
private static final int E = 421;
private static final int V = 674;
private static final String CUT_OFF = "------------------------";
private static final String CUT_OFF_END = "----------------------" +
"--------------------------------------------------------";
private static final String SPACE_9 = " ";
public static void d(String tag, String... values) {
printf(D, tag, values);
}
public static void e(String tag, String... values) {
printf(E, tag, values);
}
public static void v(String tag, String... values) {
printf(V, tag, values);
}
private static void printf(int mark, String tag, String... values) {
if (!DEBUG) {
return;
}
//需要打印的内容
StringBuffer value = new StringBuffer();
for (int i = 0; i < values.length; i++) {
value.append(values[i]);
if (i == values.length - 1) {
break;
}
value.append(", ");
}
// 打印
switch (mark) {
case D:
printfLine(D, tag);
Log.d(tag, SPACE_9 + value.toString());
Log.d(tag, CUT_OFF_END);
break;
case E:
printfLine(E, tag);
Log.e(tag, SPACE_9 + value.toString());
Log.e(tag, CUT_OFF_END);
break;
case V:
printfLine(V, tag);
Log.v(tag, SPACE_9 + value.toString());
Log.v(tag, CUT_OFF_END);
break;
}
}
private static String getPosition(String tag) {
StringBuilder sb = new StringBuilder();
StackTraceElement element = getTargetStack(tag);
if (null == element) {
return null;
}
//sb.append(".")// 我电脑的AndroidStudio有点问题,必须在这加个点,在logcat中才能定位。Androidstudio升级后,这个问题不存在了。
sb.append("(")
.append(element.getFileName())
.append(":")
.append(element.getLineNumber())
.append(")");
return sb.toString();
}
private static void printfLine(int mark, String tag) {
String startLine = CUT_OFF + getPosition(tag) + CUT_OFF;
switch (mark) {
case D:
Log.d(tag, " ");
Log.d(tag, startLine);
break;
case E:
Log.e(tag, " ");
Log.e(tag, startLine);
break;
case V:
Log.v(tag, " ");
Log.v(tag, startLine);
break;
}
}
/**
* 获取最后调用我们log的StackTraceElement
* @param tag 目标类的SimpleName
* @return
*/
private static StackTraceElement getTargetStack(String tag) {
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getClassName().contains(tag)) {
//返回调用位置的 element
return element;
}
}
return null;
}
}