android 日志文件LogUtils实例
背景
这是好久之前在网上找的一个常用类,已经忘记原文链接了,但是觉得很好用一直都在用,可以将日志写到file里面也可以定位你是在哪个类哪一行打印的日志,保存到文件的路径就是android/data/你的包名/files/目录下,然后我们就可以愉快的找问题了
importandroid.text.TextUtils;
importandroid.util.Log;
importcom.smartlink.suixing.App;
importcom.smartlink.suixing.BuildConfig;
importjava.io.BufferedWriter;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.OutputStreamWriter;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.Formatter;
importjava.util.Locale;
publicclassLogUtils{
	publicstaticString			customTagPrefix	="log";	//自定义Tag的前缀,可以是作者名
	privatestaticfinalboolean	isSaveLog		=true;		//是否把保存日志到SD卡中
	privatestaticString			cacheDirPath;
	privateLogUtils(){
	}
	//容许打印日志的类型,默认是true,设置为false则不打印
	publicstaticboolean	allowD		=BuildConfig.DEBUG;
	publicstaticboolean	allowE		=BuildConfig.DEBUG;
	publicstaticboolean	allowI		=BuildConfig.DEBUG;
	publicstaticboolean	allowV		=BuildConfig.DEBUG;
	publicstaticboolean	allowW		=BuildConfig.DEBUG;
	publicstaticboolean	allowWtf	=BuildConfig.DEBUG;
	//publicstaticbooleanallowD=true;
	//publicstaticbooleanallowE=true;
	//publicstaticbooleanallowI=true;
	//publicstaticbooleanallowV=true;
	//publicstaticbooleanallowW=true;
	//publicstaticbooleanallowWtf=true;
	privatestaticStringgenerateTag(StackTraceElementcaller){
		Stringtag="%s.%s(Line:%d)";//占位符
		StringcallerClazzName=caller.getClassName();//获取到类名
		callerClazzName=callerClazzName.substring(callerClazzName.lastIndexOf(".")+1);
		tag=String.format(tag,callerClazzName,caller.getMethodName(),caller.getLineNumber());//替换
		tag=TextUtils.isEmpty(customTagPrefix)?tag:customTagPrefix+":"+tag;
		returntag;
	}
	/***
	*打印控制台显示不了那么长的日志问题
	*
	*@parammsg
	*/
	publicstaticvoidlogE(Stringmsg){//信息太长,分段打印
		if(!allowE)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		//因为String的length是字符数量不是字节数量所以为了防止中文字符过多,
		//把4*1024的MAX字节打印长度改为2001字符数
		intmax_str_length=2001-tag.length();
		//大于4000时
		while(msg.length()>max_str_length){
			//Log.e(tag,msg.substring(0,max_str_length));
			LogUtils.e(msg.substring(0,max_str_length));
			msg=msg.substring(max_str_length);
		}
		//剩余部分
		//Log.e(tag,msg);
		LogUtils.e(msg);
	}
	/**
	*自定义的logger
	*/
	publicstaticCustomLoggercustomLogger;
	publicinterfaceCustomLogger{
		voidd(Stringtag,Stringcontent);
		voidd(Stringtag,Stringcontent,Throwabletr);
		voide(Stringtag,Stringcontent);
		voide(Stringtag,Stringcontent,Throwabletr);
		voidi(Stringtag,Stringcontent);
		voidi(Stringtag,Stringcontent,Throwabletr);
		voidv(Stringtag,Stringcontent);
		voidv(Stringtag,Stringcontent,Throwabletr);
		voidw(Stringtag,Stringcontent);
		voidw(Stringtag,Stringcontent,Throwabletr);
		voidw(Stringtag,Throwabletr);
		voidwtf(Stringtag,Stringcontent);
		voidwtf(Stringtag,Stringcontent,Throwabletr);
		voidwtf(Stringtag,Throwabletr);
	}
	publicstaticvoidd(Stringcontent){
		if(!allowD)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.d(tag,content);
		}else{
			Log.d(tag,content);
		}
	}
	publicstaticvoidd(Stringcontent,Throwabletr){
		if(!allowD)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.d(tag,content,tr);
		}else{
			Log.d(tag,content,tr);
		}
	}
	publicstaticvoide(Stringcontent){
		if(!allowE)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.e(tag,content);
		}else{
			Log.e(tag,content);
		}
		if(isSaveLog){
			point(cacheDirPath,tag,content);
		}
	}
	publicstaticvoide(Stringcontent,Throwabletr){
		if(!allowE)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.e(tag,content,tr);
		}else{
			Log.e(tag,content,tr);
		}
		if(isSaveLog){
			point(cacheDirPath,tag,tr.getMessage());
		}
	}
	publicstaticvoide(Throwabletr){
		if(!allowE)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.e(tag,"",tr);
		}else{
			Log.e(tag,"",tr);
		}
		if(isSaveLog){
			point(cacheDirPath,tag,tr.getMessage());
		}
	}
	publicstaticvoidi(Stringcontent){
		if(!allowI)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.i(tag,content);
		}else{
			Log.i(tag,content);
		}
	}
	publicstaticvoidi(Stringcontent,Throwabletr){
		if(!allowI)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.i(tag,content,tr);
		}else{
			Log.i(tag,content,tr);
		}
	}
	publicstaticvoidv(Stringcontent){
		if(!allowV)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.v(tag,content);
		}else{
			Log.v(tag,content);
		}
	}
	publicstaticvoidv(Stringcontent,Throwabletr){
		if(!allowV)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.v(tag,content,tr);
		}else{
			Log.v(tag,content,tr);
		}
	}
	publicstaticvoidw(Stringcontent){
		if(!allowW)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.w(tag,content);
		}else{
			Log.w(tag,content);
		}
	}
	publicstaticvoidw(Stringcontent,Throwabletr){
		if(!allowW)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.w(tag,content,tr);
		}else{
			Log.w(tag,content,tr);
		}
	}
	publicstaticvoidw(Throwabletr){
		if(!allowW)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.w(tag,tr);
		}else{
			Log.w(tag,tr);
		}
	}
	publicstaticvoidwtf(Stringcontent){
		if(!allowWtf)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.wtf(tag,content);
		}else{
			Log.wtf(tag,content);
		}
	}
	publicstaticvoidwtf(Stringcontent,Throwabletr){
		if(!allowWtf)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.wtf(tag,content,tr);
		}else{
			Log.wtf(tag,content,tr);
		}
	}
	publicstaticvoidwtf(Throwabletr){
		if(!allowWtf)return;
		StackTraceElementcaller=getCallerStackTraceElement();
		Stringtag=generateTag(caller);
		if(customLogger!=null){
			customLogger.wtf(tag,tr);
		}else{
			Log.wtf(tag,tr);
		}
	}
	privatestaticStackTraceElementgetCallerStackTraceElement(){
		returnThread.currentThread().getStackTrace()[4];
	}
	publicstaticvoidpoint(Stringpath,Stringtag,Stringmsg){
		if(isSDAva()){
			path=cacheDirPath;
			Datedate=newDate();
			SimpleDateFormatdateFormat=newSimpleDateFormat("",Locale.SIMPLIFIED_CHINESE);
			dateFormat.applyPattern("yyyy");
			path=path+dateFormat.format(date)+"/";
			dateFormat.applyPattern("MM");
			path+=dateFormat.format(date)+"/";
			dateFormat.applyPattern("dd");
			path+=dateFormat.format(date)+".log";
			dateFormat.applyPattern("[yyyy-MM-ddHH:mm:ss]");
			Stringtime=dateFormat.format(date);
			Filefile=newFile(path);
			if(!file.exists())createDipPath(path);
			BufferedWriterout=null;
			try{
				out=newBufferedWriter(newOutputStreamWriter(newFileOutputStream(file,true)));
				out.write(time+""+tag+""+msg+"\r\n");
			}catch(Exceptione){
				e.printStackTrace();
			}finally{
				try{
					if(out!=null){
						out.close();
					}
				}catch(IOExceptione){
					e.printStackTrace();
				}
			}
		}
	}
	/**
	*根据文件路径递归创建文件
	*
	*@paramfile
	*/
	publicstaticvoidcreateDipPath(Stringfile){
		StringparentFile=file.substring(0,file.lastIndexOf("/"));
		Filefile1=newFile(file);
		Fileparent=newFile(parentFile);
		if(!file1.exists()){
			parent.mkdirs();
			try{
				file1.createNewFile();
				LogUtils.e("日志文件的路径是"+file1.getAbsolutePath());
			}catch(IOExceptione){
				e.printStackTrace();
			}
		}
	}
	/**
	*Alittletricktoreuseaformatterinthesamethread
	*/
	privatestaticclassReusableFormatter{
		privateFormatter		formatter;
		privateStringBuilder	builder;
		publicReusableFormatter(){
			builder=newStringBuilder();
			formatter=newFormatter(builder);
		}
		publicStringformat(Stringmsg,Object...args){
			formatter.format(msg,args);
			Strings=builder.toString();
			builder.setLength(0);
			returns;
		}
	}
	privatestaticfinalThreadLocalthread_local_formatter=newThreadLocal(){
		protectedReusableFormatterinitialValue(){
			returnnewReusableFormatter();
		}
	};
	publicstaticStringformat(Stringmsg,Object...args){
		ReusableFormatterformatter=thread_local_formatter.get();
		returnformatter.format(msg,args);
	}
	publicstaticbooleanisSDAva(){
		if(cacheDirPath==null)cacheDirPath=App.getAppContext().getExternalFilesDir("log").getAbsolutePath();
		if(!TextUtils.isEmpty(cacheDirPath)){
			returntrue;
		}else{
			returnfalse;
		}
	}
}
  
补充知识:Android日志打印类LogUtils,能够定位到类名,方法名以及出现错误的行数并保存日志文件
在开发中,我们常常用打印log的方式来调试我们的应用。在Java中我们常常使用方法System.out.println()来在控制台打印日志,以便我们的调试。Android中有一个专门的类Log来实现在Android系统下日志的打印,更加方便我们定位程序出现问题的地方。
但是Android官方提供的Log类在实际项目使用中,也不是非常方便。当程序出现错误时,我们最希望的就是这个Log类能帮我们定位到是哪个类的哪个方法,甚至于是那一行出现了错误。这样就能给我们的调试带来很大的便利。
同时我们也应该想到为了应用程序的安全起见,在app正式上线之前,我们应该要把打印日志的功能关闭掉,以防别人通过Log来破解你的应用。生产模式的下打印Log,正式模式就把打印日志的功能关闭掉,要做到Log的灵活关闭与打开,也需要在原生的Log类上进行一些封装。
还有一种时候,当我们的程序出现问题崩溃了,我们希望能够收集到出现异常的原因进行分析,所以可以把Log日志保存到一个文件中,放在SD卡程序创建的目录下。也可以在用户联网的情况下,在程序的后台把出异常的Log日志文件上传到服务端,方便程序员进行分析,解决bug。
今天就给大家分享一个做项目中很实用的一个Log类LogUtils,这个类是从xUtils中提取出来,稍作修改的,有注释。
示例:
我们在MainActivity中调用一些LogUtils中的方法,注意看行数。1
接着看看控制台打印的日志是不是像MainActivity调用的那样,Log中有这个类的名字和oncreate方法名,已及当前行数;2
看到上图中的Log日志是不是很方便定位程序中的问题了,出现异常也能快速的定位到。然后把下面的Log类型在程序的任何地方设置为false则不会打印日志,使用起来相当的方便。
//容许打印日志的类型,默认是true,设置为false则不打印 publicstaticbooleanallowD=true; publicstaticbooleanallowE=true; publicstaticbooleanallowI=true; publicstaticbooleanallowV=true; publicstaticbooleanallowW=true; publicstaticbooleanallowWtf=true;
代码贴在下面:
packagecom.finddreams.log;
importjava.io.BufferedWriter;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.OutputStreamWriter;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.Formatter;
importjava.util.Locale;
importandroid.os.Environment;
importandroid.text.TextUtils;
importandroid.util.Log;
/**
*Log工具,类似android.util.Log。tag自动产生,格式:
*customTagPrefix:className.methodName(Line:lineNumber),
*customTagPrefix为空时只输出:className.methodName(Line:lineNumber)。
*/
publicclassLogUtils{
publicstaticStringcustomTagPrefix="finddreams";//自定义Tag的前缀,可以是作者名
privatestaticfinalbooleanisSaveLog=false;//是否把保存日志到SD卡中
publicstaticfinalStringROOT=Environment.getExternalStorageDirectory()
.getPath()+"/finddreams/";//SD卡中的根目录
privatestaticfinalStringPATH_LOG_INFO=ROOT+"info/";
privateLogUtils(){
}
//容许打印日志的类型,默认是true,设置为false则不打印
publicstaticbooleanallowD=true;
publicstaticbooleanallowE=true;
publicstaticbooleanallowI=true;
publicstaticbooleanallowV=true;
publicstaticbooleanallowW=true;
publicstaticbooleanallowWtf=true;
privatestaticStringgenerateTag(StackTraceElementcaller){
Stringtag="%s.%s(Line:%d)";//占位符
StringcallerClazzName=caller.getClassName();//获取到类名
callerClazzName=callerClazzName.substring(callerClazzName
.lastIndexOf(".")+1);
tag=String.format(tag,callerClazzName,caller.getMethodName(),
caller.getLineNumber());//替换
tag=TextUtils.isEmpty(customTagPrefix)?tag:customTagPrefix+":"
+tag;
returntag;
}
/**
*自定义的logger
*/
publicstaticCustomLoggercustomLogger;
publicinterfaceCustomLogger{
voidd(Stringtag,Stringcontent);
voidd(Stringtag,Stringcontent,Throwabletr);
voide(Stringtag,Stringcontent);
voide(Stringtag,Stringcontent,Throwabletr);
voidi(Stringtag,Stringcontent);
voidi(Stringtag,Stringcontent,Throwabletr);
voidv(Stringtag,Stringcontent);
voidv(Stringtag,Stringcontent,Throwabletr);
voidw(Stringtag,Stringcontent);
voidw(Stringtag,Stringcontent,Throwabletr);
voidw(Stringtag,Throwabletr);
voidwtf(Stringtag,Stringcontent);
voidwtf(Stringtag,Stringcontent,Throwabletr);
voidwtf(Stringtag,Throwabletr);
}
publicstaticvoidd(Stringcontent){
if(!allowD)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.d(tag,content);
}else{
Log.d(tag,content);
}
}
publicstaticvoidd(Stringcontent,Throwabletr){
if(!allowD)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.d(tag,content,tr);
}else{
Log.d(tag,content,tr);
}
}
publicstaticvoide(Stringcontent){
if(!allowE)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.e(tag,content);
}else{
Log.e(tag,content);
}
if(isSaveLog){
point(PATH_LOG_INFO,tag,content);
}
}
publicstaticvoide(Stringcontent,Throwabletr){
if(!allowE)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.e(tag,content,tr);
}else{
Log.e(tag,content,tr);
}
if(isSaveLog){
point(PATH_LOG_INFO,tag,tr.getMessage());
}
}
publicstaticvoidi(Stringcontent){
if(!allowI)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.i(tag,content);
}else{
Log.i(tag,content);
}
}
publicstaticvoidi(Stringcontent,Throwabletr){
if(!allowI)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.i(tag,content,tr);
}else{
Log.i(tag,content,tr);
}
}
publicstaticvoidv(Stringcontent){
if(!allowV)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.v(tag,content);
}else{
Log.v(tag,content);
}
}
publicstaticvoidv(Stringcontent,Throwabletr){
if(!allowV)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.v(tag,content,tr);
}else{
Log.v(tag,content,tr);
}
}
publicstaticvoidw(Stringcontent){
if(!allowW)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.w(tag,content);
}else{
Log.w(tag,content);
}
}
publicstaticvoidw(Stringcontent,Throwabletr){
if(!allowW)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.w(tag,content,tr);
}else{
Log.w(tag,content,tr);
}
}
publicstaticvoidw(Throwabletr){
if(!allowW)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.w(tag,tr);
}else{
Log.w(tag,tr);
}
}
publicstaticvoidwtf(Stringcontent){
if(!allowWtf)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.wtf(tag,content);
}else{
Log.wtf(tag,content);
}
}
publicstaticvoidwtf(Stringcontent,Throwabletr){
if(!allowWtf)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.wtf(tag,content,tr);
}else{
Log.wtf(tag,content,tr);
}
}
publicstaticvoidwtf(Throwabletr){
if(!allowWtf)
return;
StackTraceElementcaller=getCallerStackTraceElement();
Stringtag=generateTag(caller);
if(customLogger!=null){
customLogger.wtf(tag,tr);
}else{
Log.wtf(tag,tr);
}
}
privatestaticStackTraceElementgetCallerStackTraceElement(){
returnThread.currentThread().getStackTrace()[4];
}
publicstaticvoidpoint(Stringpath,Stringtag,Stringmsg){
if(isSDAva()){
Datedate=newDate();
SimpleDateFormatdateFormat=newSimpleDateFormat("",
Locale.SIMPLIFIED_CHINESE);
dateFormat.applyPattern("yyyy");
path=path+dateFormat.format(date)+"/";
dateFormat.applyPattern("MM");
path+=dateFormat.format(date)+"/";
dateFormat.applyPattern("dd");
path+=dateFormat.format(date)+".log";
dateFormat.applyPattern("[yyyy-MM-ddHH:mm:ss]");
Stringtime=dateFormat.format(date);
Filefile=newFile(path);
if(!file.exists())
createDipPath(path);
BufferedWriterout=null;
try{
out=newBufferedWriter(newOutputStreamWriter(
newFileOutputStream(file,true)));
out.write(time+""+tag+""+msg+"\r\n");
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
if(out!=null){
out.close();
}
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
/**
*根据文件路径递归创建文件
*
*@paramfile
*/
publicstaticvoidcreateDipPath(Stringfile){
StringparentFile=file.substring(0,file.lastIndexOf("/"));
Filefile1=newFile(file);
Fileparent=newFile(parentFile);
if(!file1.exists()){
parent.mkdirs();
try{
file1.createNewFile();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
/**
*Alittletricktoreuseaformatterinthesamethread
*/
privatestaticclassReusableFormatter{
privateFormatterformatter;
privateStringBuilderbuilder;
publicReusableFormatter(){
builder=newStringBuilder();
formatter=newFormatter(builder);
}
publicStringformat(Stringmsg,Object...args){
formatter.format(msg,args);
Strings=builder.toString();
builder.setLength(0);
returns;
}
}
privatestaticfinalThreadLocalthread_local_formatter=newThreadLocal(){
protectedReusableFormatterinitialValue(){
returnnewReusableFormatter();
}
};
publicstaticStringformat(Stringmsg,Object...args){
ReusableFormatterformatter=thread_local_formatter.get();
returnformatter.format(msg,args);
}
publicstaticbooleanisSDAva(){
if(Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)
||Environment.getExternalStorageDirectory().exists()){
returntrue;
}else{
returnfalse;
}
}
}
  
以上这篇android日志文件LogUtils实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
