下面的log记录方式是只是自己使用觉得方便的一种形式。
android程序出现问题一般有两种情况
1、直接崩溃。这个比较好找问题。可以直接通过log的error里面去定位到出错的地方。
2、运行结果效果没有符合预期。这个就需要在程序中增加log进行定位。
android.util.Log常用的方法有以下5个:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() 。根据首字母对应VERBOSE,DEBUG,INFO, WARN,ERROR。同时还要System.out.println()等。如果没有进行区分和统一使用。有时候也会觉得很乱。
这些log的区别其实不大,使用那个都可以。只是等级不一样。在lotcat里面过滤的形式不一样而已。所以通常我只使用了v和e两种log,其他的log不使用,不想去区分。
在任何一个public类里面,我们都会增加一个变量 private static final String TAG = “类名”;并且把这个TAG作为log调用的TAG参数。但是不同的类就是不同的TAG。如果VERBOSE这种log不进行过滤的话,很多不是我们应用的log都会打印出来进行干扰。所以log肯定是需要进行过滤的。但是如果通过TAG过滤的话很难区分哪些log是先出现,哪些log是后面出现的。所以希望是统一的TAG。
一般我们打印的log看有没有执行某个函数通常是Log.i(TAG,"onCreate")。如果每个函数都这样打log的话,要频繁的输入函数的名字,所以会感觉非常不方便,所以我们需要封装类似于C/C++中的__FILE__、__FUNC__、__LINE__等功能。
下面的DBG.java就封装了上面的功能。比如可以通过DBG.log(TAG,DBG._FUNC_());来看有没有执行到某个函数。
package com.wyd.music.vo;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.util.Log;
/**
* 调试中的日志输出以及类似<br>
* C/C++中的__FILE__、__FUNC__、__LINE__等功能
*
* @author WangYD
* @time 2015年8月4日
*/
public class DBG {
public static final String TAG = "DBG";
public static final boolean D = true;
public static void log(String tag, String msg) {
if (D) {
Log.i(TAG, tag + "-> " + msg); //统一TAG
Log.i(tag, msg);//有时候也需要进一步过滤某个类的TAG
}
}
public static void log(String tag, String msg, Exception e) {
if (D) {
Log.e(TAG, tag + "-> " + msg, e);
Log.e(tag, msg, e);
}
}
/**
* 当前文件名
*
* @return
*/
public static String _FILE_() {
if (!D)
return "release";
StackTraceElement traceElement = ((new Exception()).getStackTrace())[1];
return traceElement.getFileName();
}
/**
* 当前方法名
*
* @return
*/
public static String _FUNC_() {
if (!D)
return "release";
StackTraceElement traceElement = ((new Exception()).getStackTrace())[1];
return traceElement.getMethodName();
}
/**
* 当前行号
*
* @return
*/
public static int _LINE_() {
if (!D)
return 0;
StackTraceElement traceElement = ((new Exception()).getStackTrace())[1];
return traceElement.getLineNumber();
}
/**
* 当前时间
*
* @return
*/
@SuppressLint("SimpleDateFormat")
public static String _TIME_() {
if (!D)
return "release";
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
return sdf.format(now);
}
public static void main(String[] args) {
System.out.println(DBG._FILE_());
System.out.println(DBG._FUNC_());
System.out.println(DBG._LINE_());
System.out.println(DBG._TIME_());
System.out.println(DBG.getFileLineMethod());
System.out.println("&&&&&&&&&&&&");
StackTraceElement traceElement = ((new Exception()).getStackTrace())[0];
System.out.println(traceElement.getClassName());
System.out.println(traceElement.getFileName());
System.out.println(traceElement.getLineNumber());
System.out.println(traceElement.getMethodName());
System.out.println("&&&&&&&&&&&&");
XXXX();
}
public static void XXXX() {
YYYY();
}
public static void YYYY() {
ZZZZ();
}
public static void ZZZZ() {
StackTraceElement[] traceElement = ((new Exception()).getStackTrace());
for (int i = 0; i < traceElement.length; i++) {
System.out.println(traceElement[i].getClassName());
System.out.println(traceElement[i].getFileName());
System.out.println(traceElement[i].getLineNumber());
System.out.println(traceElement[i].getMethodName());
System.out.println("***************");
}
}
}
上面的main函数是在java里面进行测试一段代码。主要是想看 StackTraceElement 这个类是什么。初步理解就是运行的轨迹,调用的轨迹吧。XXXX(),YYYY(),ZZZZ()等函数的嵌套。嵌套的越多StackTraceElement返回的数组长度越大。因为一般我们在我的函数里面调用了DBG._FUN_();在_FUN_里面调用了((new Exception()).getStackTrace()); 所以返回的StackTraceElement[0]是_FUN_里面的
StackTraceElement[1]则是调用DBG._FUN_()里面的。
上面main打印出来如下:行数其实是调用到((new Exception()).getStackTrace());的行数
DBG.java
main
56
2015-08-04 11:17:38.264
[DBG.java | 58 | main]
&&&&&&&&&&&&
com.pax.DBG
DBG.java
61
main
&&&&&&&&&&&&
com.pax.DBG
DBG.java
76
ZZZZ
***************
com.pax.DBG
DBG.java
87
YYYY
***************
com.pax.DBG
DBG.java
72
XXXX
***************
com.pax.DBG
DBG.java
67
main
***************