一、Android打印日志,一般做法都是在类中定义一个常量Tag,并且每次打印都需要输入tag。
这样做法有好多弊端:
1、效率太低。
2、开发完想要去掉打印的话,那还得一个一个找出来并屏蔽掉,特别麻烦。
3、打印不规范,特别是经过多个开发者手,打印风格那是五花八门的,分析起来累。
二、根据以上问题,设计了一个打印工具类LogUtil,具备以下功能:
1、有个统一风格。
2、不用定义和输入tag,tag自动包含打印所在位置的类名和方法名。
3、打印分级别,可以统一屏蔽掉或者只屏蔽部分打印。
4、也可以设置应用标识,方便筛选某个应用的打印。
5、也可以显示打印所在类的行数,方便查找。
代码也很简洁,如下:
package com.dway.common.utils;
import android.text.TextUtils;
import android.util.Log;
/**
* 打印工具类
* 可自动把调用位置所在的类名和方法名作为tag,并可设置打印级别
* ldw
*/
public class LogUtil {
//以下为打印级别,级别从低到高
public static final int LOG_LEVEL_VERBOSE = 1;
public static final int LOG_LEVEL_DEBUG = 2;
public static final int LOG_LEVEL_INFO = 3;
public static final int LOG_LEVEL_WARN = 4;
public static final int LOG_LEVEL_ERROR = 5;
public static final int LOG_LEVEL_NOLOG = 6;
private static String AppName = "";
private static boolean PrintLine = false;
private static int LogLevel = LOG_LEVEL_VERBOSE;
/**
* 可在打印的TAG前添加应用名标识,不设置则不输出
*/
public static void setAppName(String appName){
AppName = appName;
}
/**
* 是否输出打印所在的行数,默认不输出
*/
public static void setPrintLine(boolean enable){
PrintLine = enable;
}
/**
* 设置打印级别,且只有等于或高于该级别的打印才会输出
*/
public static void setLogLevel(int logLevel){
LogLevel = logLevel;
}
public static void v(String msg){
if(LogLevel <= LOG_LEVEL_VERBOSE) {
String tag = generateTag();
Log.v(tag, msg);
}
}
public static void d(String msg){
if(LogLevel <= LOG_LEVEL_DEBUG) {
String tag = generateTag();
Log.d(tag, msg);
}
}
public static void i(String msg){
if(LogLevel <= LOG_LEVEL_INFO) {
String tag = generateTag();
Log.i(tag, msg);
}
}
public static void w(String msg){
if(LogLevel <= LOG_LEVEL_WARN) {
String tag = generateTag();
Log.w(tag, msg);
}
}
public static void e(String msg){
if(LogLevel <= LOG_LEVEL_ERROR) {
String tag = generateTag();
Log.e(tag, msg);
}
}
/**
* 生成tag
*/
private static String generateTag() {
StackTraceElement caller = Thread.currentThread().getStackTrace()[4];
String callerClazzName = caller.getClassName();
callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1);
String tag = "%s.%s";
if(!TextUtils.isEmpty(AppName)){
tag = AppName + "__" + tag;
}
if(PrintLine){
tag += "(Line:%d)";
tag = String.format(tag, callerClazzName, caller.getMethodName(), caller.getLineNumber());
}else{
tag = String.format(tag, callerClazzName, caller.getMethodName());
}
return tag;
}
}
三、使用
设置应用名和设置打印级别:
LogUtil.setAppName("Player");
LogUtil.setLogLevel(LogUtil.LOG_LEVEL_VERBOSE);
在任何地方打印:
LogUtil.v("test log");
四、更新
后来觉得打印TAG有点长,又进行了简化
package com.dawy.common.utils;
import android.text.TextUtils;
import android.util.Log;
/**
* 打印工具类
* 可自动把调用位置所在的类名和方法名作为tag,并可设置打印级别
* dway
*/
public class LogUtil {
//以下为打印级别,级别从低到高
public static final int LOG_LEVEL_VERBOSE = 1;
public static final int LOG_LEVEL_DEBUG = 2;
public static final int LOG_LEVEL_INFO = 3;
public static final int LOG_LEVEL_WARN = 4;
public static final int LOG_LEVEL_ERROR = 5;
public static final int LOG_LEVEL_NOLOG = 6;
private static String AppName = "";
private static boolean PrintLine = false;
private static int LogLevel = LOG_LEVEL_VERBOSE;
/**
* 可在打印的TAG前添加应用名标识,不设置则不输出
*/
public static void setAppName(String appName){
AppName = appName;
}
/**
* 是否输出打印所在的行数,默认不输出
*/
public static void setPrintLine(boolean enable){
PrintLine = enable;
}
/**
* 设置打印级别,且只有等于或高于该级别的打印才会输出
*/
public static void setLogLevel(int logLevel){
LogLevel = logLevel;
}
public static void v(){
log(LOG_LEVEL_VERBOSE, "");
}
public static void d(){
log(LOG_LEVEL_DEBUG, "");
}
public static void i(){
log(LOG_LEVEL_INFO, "");
}
public static void w(){
log(LOG_LEVEL_WARN, "");
}
public static void e(){
log(LOG_LEVEL_ERROR, "");
}
public static void v(String msg){
if(LogLevel <= LOG_LEVEL_VERBOSE) {
log(LOG_LEVEL_VERBOSE, msg);
}
}
public static void d(String msg){
if(LogLevel <= LOG_LEVEL_DEBUG) {
log(LOG_LEVEL_DEBUG, msg);
}
}
public static void i(String msg){
if(LogLevel <= LOG_LEVEL_INFO) {
log(LOG_LEVEL_INFO, msg);
}
}
public static void w(String msg){
if(LogLevel <= LOG_LEVEL_WARN) {
log(LOG_LEVEL_WARN, msg);
}
}
public static void e(String msg){
if(LogLevel <= LOG_LEVEL_ERROR) {
log(LOG_LEVEL_ERROR, msg);
}
}
private static void log(int logLevel, String msg) {
StackTraceElement caller = Thread.currentThread().getStackTrace()[4];
String callerClazzName = caller.getClassName();
if(callerClazzName.contains(".")) {
callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1);
}
if(callerClazzName.contains("$")){
callerClazzName = callerClazzName.substring(0, callerClazzName.indexOf("$"));
}
String tag = callerClazzName;
if(!TextUtils.isEmpty(AppName)){
tag = AppName + "_" + tag;
}
if(PrintLine) {
tag += "(Line:%d)";
tag = String.format(tag, caller.getLineNumber());
}
tag = String.format(tag, callerClazzName);
String message = "---"+caller.getMethodName()+"---"+msg;
switch (logLevel){
case LOG_LEVEL_VERBOSE:
Log.v(tag, message);
break;
case LOG_LEVEL_DEBUG:
Log.d(tag, message);
break;
case LOG_LEVEL_INFO:
Log.i(tag, message);
break;
case LOG_LEVEL_WARN:
Log.w(tag, message);
break;
case LOG_LEVEL_ERROR:
Log.e(tag, message);
break;
case LOG_LEVEL_NOLOG:
break;
}
}
}
使用方法不变,另外增加了不带参数的方法,方便一些只需要打印方法名的地方使用。
LogUtil.v();//仅打印方法名