不知众多Android开发者是否在程序开发的工程中也遇到过下面的问题:
0.如何在众多log中快速找到你设置打印的那行log?
1.是否还在不断的切换标签来查看使用不同TAG标签打印的log?
2.找到需要的log后是否苦恼不能快速定位到Java源代码中查看?
起初我也和大多数Android开发者一样,使用官方的打印log的方法,设置TAG,在Eclipse里面设置过滤标签,切换来回的看Log,可是这样却效率很低,会遇到上面所述的问题,那么现在我就把学习到的一种方便快捷的打印Log的方法分享给大家,有不对的地方还望不吝赐教,谢谢。
Log类具有的功能
0.使用一个标签来标记当前的AP(避免设置过多的TAG来过滤显示不同Java文件下的Log)
1.支持多用户打印Log(在AP比较大,文件比较多,每人负责的模块不同时,可以使用自己的log来打印,这样看log的时候可以快速筛选出当前AP中你所设置的Log,比如只看 kesen的log就可以在Eclipse的filter里面输入kesen,这样显示的就都是你的log了)
2.显示当前的线程名
3.显示当前的Java文件与打印log的行号,便于快速定位到源文件
4.显示当前是在那个方法体里面
5.最后显示你设置打印出来的信息
下面是一个打印Log的工具类:
/**
* The class for print log
* @author kesenhoo
*
*/
public class MyLogger
{
private final static booleanlogFlag= true;
public final static Stringtag= "[AppName]";
private final static intlogLevel= Log.VERBOSE;
private static Hashtable<String, MyLogger>sLoggerTable= new Hashtable<String, MyLogger>();
private StringmClassName;
private static MyLoggerjlog;
private static MyLoggerklog;
private static final StringJAMES= "@james@ ";
private static final StringKESEN= "@kesen@ ";
private MyLogger(String name)
{
mClassName = name;
}
/**
*
* @param className
* @return
*/
@SuppressWarnings("unused")
private static MyLogger getLogger(String className)
{
MyLogger classLogger = (MyLogger) sLoggerTable.get(className);
if(classLogger == null)
{
classLogger = new MyLogger(className);
sLoggerTable.put(className, classLogger);
}
return classLogger;
}
/**
* Purpose:Mark user one
* @return
*/
public static MyLogger kLog()
{
if(klog == null)
{
klog = new MyLogger(KESEN);
}
return klog;
}
/**
* Purpose:Mark user two
* @return
*/
public static MyLogger jLog()
{
if(jlog == null)
{
jlog = new MyLogger(JAMES);
}
return jlog;
}
/**
* Get The Current Function Name
* @return
*/
private String getFunctionName()
{
StackTraceElement[] sts = Thread.currentThread().getStackTrace();
if(sts == null)
{
return null;
}
for(StackTraceElement st : sts)
{
if(st.isNativeMethod())
{
continue;
}
if(st.getClassName().equals(Thread.class.getName()))
{
continue;
}
if(st.getClassName().equals(this.getClass().getName()))
{
continue;
}
return mClassName + "[ " + Thread.currentThread().getName() + ": "
+ st.getFileName() + ":" + st.getLineNumber() + " "
+ st.getMethodName() + " ]";
}
return null;
}
/**
* The Log Level:i
* @param str
*/
public void i(Object str)
{
if(logFlag)
{
if(logLevel <= Log.INFO)
{
String name = getFunctionName();
if(name != null)
{
Log.i(tag, name + " - " + str);
}
else
{
Log.i(tag, str.toString());
}
}
}
}
/**
* The Log Level:d
* @param str
*/
public void d(Object str)
{
if(logFlag)
{
if(logLevel <= Log.DEBUG)
{
String name = getFunctionName();
if(name != null)
{
Log.d(tag, name + " - " + str);
}
else
{
Log.d(tag, str.toString());
}
}
}
}
/**
* The Log Level:V
* @param str
*/
public void v(Object str)
{
if(logFlag)
{
if(logLevel <= Log.VERBOSE)
{
String name = getFunctionName();
if(name != null)
{
Log.v(tag, name + " - " + str);
}
else
{
Log.v(tag, str.toString());
}
}
}
}
/**
* The Log Level:w
* @param str
*/
public void w(Object str)
{
if(logFlag)
{
if(logLevel <= Log.WARN)
{
String name = getFunctionName();
if(name != null)
{
Log.w(tag, name + " - " + str);
}
else
{
Log.w(tag, str.toString());
}
}
}
}
/**
* The Log Level:e
* @param str
*/
public void e(Object str)
{
if(logFlag)
{
if(logLevel <= Log.ERROR)
{
String name = getFunctionName();
if(name != null)
{
Log.e(tag, name + " - " + str);
}
else
{
Log.e(tag, str.toString());
}
}
}
}
/**
* The Log Level:e
* @param ex
*/
public void e(Exception ex)
{
if(logFlag)
{
if(logLevel <= Log.ERROR)
{
Log.e(tag, "error", ex);
}
}
}
/**
* The Log Level:e
* @param log
* @param tr
*/
public void e(String log, Throwable tr)
{
if(logFlag)
{
String line = getFunctionName();
Log.e(tag, "{Thread:" + Thread.currentThread().getName() + "}"
+ "[" + mClassName + line + ":] " + log + "\n", tr);
}
}
}
关于里面的代码就不做解释了,大家看看应该差不多
使用案例:
这是我写的一个简单的带有一个button与textview的Activity,演示一下点击button与Activity的常规生命周期。
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ActivityMain extends Activity
{
private MyLogger logger = MyLogger.kLog();
private MyLogger logger2 = MyLogger.jLog();
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
logger.i("This is log [01]");
setContentView(R.layout.main);
Button button = (Button) this.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
logger2.i("This is James action button.OnClick");
}
});
}
@Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
logger.d("This is kesen log [02]");
}
@Override
protected void onPause()
{
// TODO Auto-generated method stub
super.onPause();
logger.w("This is kesen log [03]");
}
@Override
protected void onStop()
{
// TODO Auto-generated method stub
super.onStop();
logger.v("This is kesen log [04]");
}
@Override
protected void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
logger.e("This is kesen log [05]");
}
}
下面是用这个log工具类打印出来的Log效果:
从上面的解释差不多可以看出这个Log工具类具有的功能:
0.使用一个标签来标记当前的AP
1.支持多用户打印Log(在AP比较大,文件比较多,每人负责的模块不同时,可以使用自己的log来打印,这样看log的时候可以快速筛选出当前AP中你所设置的Log,比如只看 kesen的log就可以在Eclipse的filter里面输入kesen,这样显示的就都是你的log了)
2.显示当前的线程名
3.显示当前的Java文件与打印log的行号,便于快速定位到源文件
4.显示当前是在那个方法体里面
5.最后显示你设置打印出来的信息
写的不好,有不对的地方还请见谅,谢谢!