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