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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。