Android 中的Log类在调试过程中用来输出一些调试信息,或者用来分析程序执行流程。
我在开始接触android时常常如下使用
@Override
protected void onRestart() {
Log.i("TestActivity","onRestart");
super.onRestart();
}
@Override
protected void onStart() {
Log.i("TestActivity","onStart");
super.onStart();
}
@Override
protected void onResume() {
Log.i("TestActivity","onResume");
super.onResume();
}
这里就有一个问题,这里的tag被重复写了N次,如果要修改也要修改N处,显然是不好的。
需要改进一下,定义一个变量,修改只需要改一处就好。其实Android的代码也是这样的。
增加变量 private static final String TAG = "TestActivity";
@Override
protectedvoidonStart() {
Log.i(TAG,"onStart");
super.onStart();
}
@Override
protectedvoidonResume() {
Log.i(TAG,"onResume");
super.onResume();
}
@Override
protectedvoidonStop() {
Log.i(TAG,"onStop");
super.onStop();
}
在软件开发完成了,用不到的代码不应该存在,调试的信息也应该关闭之,比如上面代码中加的log信息,
这样就需要去一个一个删除之,很不爽,关键是万一有bug,需要有些信息,又得添加一遍,显然不是个好事情。 所以进一步做了修改。添加一个开关,private static final Boolean LOG_OUT = true;
@Override
protectedvoid onStart() {
if(LOG_OUT) Log.i(TAG, "onStart");
super.onStart();
}
@Override
protectedvoidonResume() {
if(LOG_OUT)Log.i(TAG,"onResume");
super.onResume();
}
@Override
protectedvoidonStop() {
if(LOG_OUT)Log.i(TAG,"onStop");
super.onStop();
}
新问题又来了,if(LOG_OUT)在代码中多次出现,看着也不爽,我又做了下改进,新增加一个类
publicclassMLog {
privatestaticfinalBooleanLOG_OUT=true;
publicstaticintd(String TAG, String msg) {
if (!LOG_OUT) {
return-1;
}
returnLog.d(TAG,msg);
}
publicstaticinti(String TAG, String msg) {
if(!LOG_OUT){
return-1;
}
returnLog.i(TAG,msg);
}
publicstaticintv(String TAG, String msg) {
if(!LOG_OUT){
return-1;
}
returnLog.v(TAG,msg);
}
publicstaticintw(String TAG, String msg) {
if(!LOG_OUT){
return-1;
}
returnLog.w(TAG,msg);
}
publicstaticinte(String TAG, String msg) {
if(!LOG_OUT){
return-1;
}
returnLog.e(TAG,msg);
}
}
修改后的代码如下:
@Override
protectedvoidonStart() {
MLog.i(TAG,"onStart");
super.onStart();
}
@Override
protectedvoidonResume() {
MLog.i(TAG,"onResume");
super.onResume();
}
@Override
protectedvoidonStop() {
MLog.i(TAG,"onStop");
super.onStop();
}
这里有个注意点,publicstaticintv(String TAG, Stringmsg)这里的行参TAG,
从android风格来看这里应该用tag比较统一,但是在我编码的过程中发现(由于我是用eclipse自动提示),
这里改为大写比较方便,因为我一般在代码里定义tag变量为TAG,这样自动提升是,就正好是TAG。
我常常会跟程序流程,publicstaticintv(String TAG, String msg);这里的msg很多时候就是函数名,比如之前看到示例。于是新曾一个类:
publicclassLogInfo {
privatestaticfinalintLENGTH= 5;
privatestaticfinalbooleanDEBUG=true;
enumInfoKind{
FILE_NAME,
METHOD_NAME,
CLASS_NAME,
LINE_NUM
}
publicstaticString getFileName() {
returngetInfo(InfoKind.FILE_NAME);
}
publicstaticString getMethodName() {
returngetInfo(InfoKind.METHOD_NAME);
}
publicstaticString getClassName() {
returngetInfo(InfoKind.CLASS_NAME);
}
publicstatic String getLineNumber() {
returngetInfo(InfoKind.LINE_NUM);
}
private static String getInfo(InfoKind kind) {
String ret ="";
if(!DEBUG){
return ret;
}
StackTraceElement[]stackTraceElements = Thread.currentThread().getStackTrace();
if(stackTraceElements !=null && stackTraceElements.length>=LENGTH){
StackTraceElementstackTraceElement = stackTraceElements[LENGTH- 1];
switch(kind) {
caseFILE_NAME:
ret= stackTraceElement.getFileName();
break;
caseMETHOD_NAME:
ret= stackTraceElement.getMethodName();
break;
caseCLASS_NAME:
ret= stackTraceElement.getClassName();
break;
caseLINE_NUM:
ret= Integer.toString(stackTraceElement.getLineNumber());
break;
default:
break;
}
}
returnret;
}
staticStackTraceElement getInfoInternal(intlength) {
StackTraceElementret =null;
if(!DEBUG){
returnret;
}
StackTraceElement[]stackTraceElements = Thread.currentThread().getStackTrace();
if(stackTraceElements !=null&& stackTraceElements.length>= length) {
ret= stackTraceElements[length - 1];
}
returnret;
}
}
类MLog增加新方法
publicstaticintprintMethodName(String TAG) {
if(!LOG_OUT){
return-1;
}
Stringmsg ="";
StackTraceElementinfo = LogInfo.getInfoInternal(LENGTH);
if(info !=null){
msg= info.getMethodName() +" # Line "+ info.getLineNumber();
}
return Log.i(TAG,msg);
}
这样代码就改为了
@Override
protectedvoidonStart() {
MLog.printMethodName(TAG);
super.onStart();
}
@Override
protectedvoidonResume() {
MLog.printMethodName(TAG);
super.onResume();
}
@Override
protectedvoidonStop() {
MLog.printMethodName(TAG);
super.onStop();
}
跟踪代码有时候还需要打印出栈,为了使用方便,在类MLog中封装方法
publicstaticintprintStackTrace(String TAG) {
if(!LOG_OUT){
return-1;
}
StackTraceElement[]stackTraceElements =newException().getStackTrace();
if(stackTraceElements !=null){
Log.d(TAG,"printStackTrace:");
for(int i = 1; i < stackTraceElements.length;i++) {
Log.d(TAG,stackTraceElements[i].toString());
}
}
return 0;
}
以上就是我对log使用的一点心得,附上这两个类文件
http://download.youkuaiyun.com/detail/jypeitao/4999245