在Android开发过程中经常使用Log打印一些调试的信息,比如:
Log.d(TAG, "xxxxx");
但是,每一个类都要定义一个TAG,一般TAG等于类名本身,比较繁琐.更重要的是,每次还要带上这个参数.如果打印的信息比较多或者一个类的代码数量比较长时,不太方便查找Log的位置.那么有没有一种方法,解决上面的问题呢?
问题分析
- 每个类的TAG等于类名,那么能不能自己去寻找类名呢?
- 能不能找到打印log所在的位置呢?
答案是肯定的!在Java中可以使用Throwable类获取栈的信息.
StackTraceElement[] elements = new Throwable().getStackTrace();
String className = elements[1].getFileName();
String methodName = elements[1].getMethodName();
int lineNumber = elements[1].getLineNumber();
通过此方法可以获取类名,方法名,行号信息.获取到信息后还需在包装一下,因为是Debug时的Log就取名DLog吧.
那么Dlog中肯定要有一个Log的实例,还要与Log方法同名的方法,比如v(),d(),e(),w(),i()等.如下所示:
public class DLog {
private static String className; //所在的类名
private static String methodName; //所在的方法名
private static int lineNumber; //所在行号
/**
* 私有化构造器
*/
private DLog() {}
/**
* 是否处于调试模式
*/
public static boolean isDebuggable() {
return BuildConfig.DEBUG;
}
/**
* 创建Log信息
*/
private static String createLog(String log) {
StringBuffer buffer = new StringBuffer();
buffer.append("[");
buffer.append(methodName);
buffer.append(":");
buffer.append(lineNumber);
buffer.append("]");
buffer.append(log);
return buffer.toString();
}
/**
* 获取类名,方法名,行号
*/
private static void getMethodNames(StackTraceElement[] sElements) {
className = sElements[1].getFileName();
methodName = sElements[1].getMethodName();
lineNumber = sElements[1].getLineNumber();
}
public static void v(String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.v(className, createLog(message));
}
public static void d(String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.d(className, createLog(message));
}
public static void i(String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.i(className, createLog(message));
}
public static void w(String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.w(className, createLog(message));
}
public static void e(String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.e(className, createLog(message));
}
}
这样好了,即能自己找到类名,又能打印出Log信息所在的位置.且慢,还有一个问题:
如果一个项目中使用了很多Log输出,项目结束时又不允许在打印这些信息怎么办?难道要一个一个删除?
一个一个删除太麻烦了,谁让我们都想偷懒呢!为何我们不在上面的那个类加个控制,不想输出可以一键屏蔽多好呀.
Log中的信息是有类别的,我们可以给每个类别分个序号,在来一个控制序号的级别,这样就可以控制显示的类别,
/**
* 包装后的Log输出,可控制显示哪些级别的LOG
* @author Administrator
*
*/
public class DLog {
private static String className; //所在的类名
private static String methodName; //所在的方法名
private static int lineNumber; //所在行号
public static final int VERBOSE = 1; //显示Verbose及以上的Log
public static final int DEBUG = 2; //显示Debug及以上的Log
public static final int INFO = 3; //显示Info及以上的Log
public static final int WARN = 4; //显示Warn及以上的Log
public static final int ERROR = 5; //显示Error及以上的Log
public static final int NOTHING = 6; //全部不显示
public static final int LEVEL = VERBOSE; //控制显示的级别
private DLog() {
}
public static boolean isDebuggable() {
return BuildConfig.DEBUG;
}
private static String createLog(String log) {
StringBuffer buffer = new StringBuffer();
buffer.append("[");
buffer.append(methodName);
buffer.append(":");
buffer.append(lineNumber);
buffer.append("]");
buffer.append(log);
return buffer.toString();
}
private static void getMethodNames(StackTraceElement[] sElements) {
className = sElements[1].getFileName();
methodName = sElements[1].getMethodName();
lineNumber = sElements[1].getLineNumber();
}
public static void v(String message) {
if (!isDebuggable()) {
return;
}
if (LEVEL <= VERBOSE) {
getMethodNames(new Throwable().getStackTrace());
Log.v(className, createLog(message));
}
}
public static void d(String message) {
if (!isDebuggable()) {
return;
}
if (LEVEL <= DEBUG) {
getMethodNames(new Throwable().getStackTrace());
Log.d(className, createLog(message));
}
}
public static void i(String message) {
if (!isDebuggable()) {
return;
}
if (LEVEL <= INFO) {
getMethodNames(new Throwable().getStackTrace());
Log.i(className, createLog(message));
}
}
public static void w(String message) {
if (!isDebuggable()) {
return;
}
if (LEVEL <= WARN) {
getMethodNames(new Throwable().getStackTrace());
Log.w(className, createLog(message));
}
}
public static void e(String message) {
if (!isDebuggable()) {
return;
}
if (LEVEL <= ERROR) {
getMethodNames(new Throwable().getStackTrace());
Log.e(className, createLog(message));
}
}
}