写了个android简洁的日志打印工具类。
2013-09-17 00:00
239 查看
package mma.demo.exception; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.regex.Pattern; import android.content.Context; import android.os.Environment; import android.util.Log; /** * 打印工具类 * @author meimuan * 功能点:<p> * <ul> * <li>可以控制打印输出</li> * <li>可以简便打印,经过包装得到精准特定格式的日志信息</li> * <li>可以直接打印异常</li> * <li>可以定位异常信息</li> * <li>可以便捷统一修改,优化</li> * <li>^^^^^^^^^^^^^^^^^^^^^^^^^^^^</li> * <li>同步输出日志到本地sdcard文件</li> * </ul> * <p> * 需要注册权限: * <table> * <tr> * <td>* 读写SD卡权限 </td><td>android.permission.WRITE_EXTERNAL_STORAGE</td> * </tr> * <tr> * <td>? 网络权限 </td><td>android.permission.INTERNET</td> * </tr> * </table> * </p> * <p> * 说明:<br/> * 1. 日志是针对天数级别的,自动生成的日志名称yyyyMMdd.log形式。</br> * 2. 如果当天的日志需要新开一个(比如:日志很大了,需要从新生成一个) * </p> */ public class LogUtil { /** 控制打印级别 在level级别之上才可以被打印出来 */ public static int LEVEL = 3; /** 打印级别为V,对应Log.v*/ public final static int V = 1; /** 打印级别为W,对应Log.w*/ public final static int W = 2; /** 打印级别为I,对应Log.i*/ public final static int I = 3; /** 打印级别为D,对应Log.d*/ public final static int D = 4; /** 打印级别为E,对应Log.e*/ public final static int E = 5; /** 最高级别打印,强制性打印,LEVEL无法关闭。 */ private final static int P = Integer.MAX_VALUE; /** 打印修饰符号*/ private static final String _L = "["; private static final String _R = "]"; /** 是否同步输出到本地日志文件 */ private static boolean IS_SYNS = false; /** 打印日志保存路径*/ private static String LOG_FILE_DIR = ""; /** 生成一个日期文件名格式的日式格式对象*/ private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd",Locale.getDefault()); /** 是否新建一个日志文件。*/ private static boolean IF_START_NEWLOG = true; /** 保存创建的文件路径 */ private static String CURRENT_LOG_NAME = ""; /** 针对天数级别的。如果当天已经存在一个LOG了,而使用者需要新开一个LOG,那么将计数 */ private static int FILE_LOG_COUNT = 0; /** 单个日志的最大的容量,如果一个日志太大了,打开会影响效率*/ private static int LOG_MAX_SIZE = 6 * 1024 * 1024; /** 检测文件目的地址是否正确 */ private static Pattern pattern = Pattern.compile("(\\w+/)+"); /** 设置是否同步记录信息或者异常到日志文件。*/ public static final void setSyns(boolean flag) { synchronized (LogUtil.class){ IS_SYNS = flag; } } /** 开启一个新的LOG */ public static final void startNewLog() { IF_START_NEWLOG = true; } /** * 打印信息 * @param message */ public static final void i(String message) { if (LEVEL <= I) { Log.i(getTag(message), message); if (IS_SYNS) { LogFile.writeLog(message); } } } public static final void i(Exception exp) { if (LEVEL <= I) { Log.i(getTag(exp),getMessage(exp)); if (IS_SYNS) { LogFile.writeLog(exp); } } } public static final void e(String message) { if (LEVEL <= E) { Log.e(getTag(message), message); if (IS_SYNS) { LogFile.writeLog(message); } } } public static final void e(Exception exp) { if (LEVEL <= E) { Log.e(getTag(exp),getMessage(exp)); if (IS_SYNS) { LogFile.writeLog(exp); } } } public static final void w(String message) { if (LEVEL <= W) { Log.w(getTag(message), message); if (IS_SYNS) { LogFile.writeLog(message); } } } public static final void w(Exception exp) { if (LEVEL <= W) { Log.w(getTag(exp),getMessage(exp)); if (IS_SYNS) { LogFile.writeLog(exp); } } } public static final void v(String message) { if (LEVEL <= V) { Log.v(getTag(message), message); if (IS_SYNS) { LogFile.writeLog(message); } } } public static final void v(Exception exp) { if (LEVEL <= V) { Log.v(getTag(exp),getMessage(exp)); if (IS_SYNS) { LogFile.writeLog(exp); } } } public static final void d(String message) { if (LEVEL <= D) { Log.d(getTag(message), message); if (IS_SYNS) { LogFile.writeLog(message); } } } public static final void d(Exception exp) { if (LEVEL <= D) { Log.d(getTag(exp),getMessage(exp)); if (IS_SYNS) { LogFile.writeLog(exp); } } } /** * 强制打印信息 * @param message */ public static final void print(String message) { if (LEVEL <= P) { Log.e(getTag(message), message); if (IS_SYNS) LogFile.writeLog(message); } } /** * 强制打印异常 * @param exp */ public static final void print(Exception exp) { if (LEVEL <= P) { Log.e(getTag(exp), getMessage(exp)); if (IS_SYNS) LogFile.writeLog(exp); } } /** 获取一个Tag打印标签 * @param msg * @return * @since JDK 1.5 */ private static String getTag(String msg) { if (msg != null) { //since jdk 1.5 if (Thread.currentThread().getStackTrace().length > 0) { String name = Thread.currentThread().getStackTrace()[0].getClassName(); return _L + name.substring(name.lastIndexOf(".") + 1) + _R; } } return _L + "null" + _R; } /** * 跟据变量获取一个打印的标签。 * @param exp * @return */ private static String getTag(Exception exp) { if (exp != null) { if (exp.getStackTrace().length > 0) { String name = exp.getStackTrace()[0].getClassName(); return _L + name.substring(name.lastIndexOf(".") + 1) + _R; } return _L + "exception" + _R; } return _L + "null" + _R; } /** * 获取Exception的简便异常信息 * @param exp * @return */ private static String getMessage(Exception exp) { StringBuilder sb = new StringBuilder(); StackTraceElement[] element = exp.getStackTrace(); int n = 0; sb.append("\n"); sb.append(exp.toString()); sb.append("\n"); for (StackTraceElement e : element) { sb.append(e.getClassName()); sb.append("."); sb.append(e.getMethodName()); sb.append("["); sb.append(e.getLineNumber()); sb.append("]"); sb.append("\n"); n++; if (n >= 2) break; } if (exp.getCause() != null) { sb.append("Caused by: "); sb.append(exp.getMessage()); } return sb.toString(); } /** 自定义保存文件路径,如果是多重路径,请以xxx/xxx/xxx 形式的‘文件夹’ * @parma path : 文件夹名称 * * [将自动以当前时间为文件名拼接成完整路径。请慎用] * */ public final static void setLogFilePath(String path) { String url = SDcardUtil.getPath() + File.separator + path; boolean flag = pattern.matcher(url).matches(); if (flag) { LOG_FILE_DIR = url; } else { LogFile.print("the url is not match file`s dir"); } } /** 设置默认路径,以包名为格式的文件夹*/ public final static void setDefaultFilePath(Context context) { String pkName = context.getPackageName().replaceAll("\\.", "\\/"); setLogFilePath(pkName); } /** 获取时间字符串 */ private static String getCurrTimeDir() { return sdf.format(new Date()); } /** LOG定制类。 * 输出LOG到日志。 */ private static class LogFile { /** 内部强制性打印使用。区分print , 是为了解决无限循环打印exception*/ private static void print(String msg) { if (LEVEL <= P) { Log.e(getTag(msg), msg); } } /** * 打印信息 * @param message */ public static synchronized void writeLog(String message) { File f = getFile(); if (f != null) { try { FileWriter fw = new FileWriter(f , true); BufferedWriter bw = new BufferedWriter(fw); bw.append("\n"); bw.append(message); bw.append("\n"); bw.flush(); bw.close(); fw.close(); } catch (IOException e) { print("writeLog error, " + e.getMessage()); } } else { print("writeLog error, due to the file dir is error"); } } /** * 打印异常 * @param exp */ public static synchronized void writeLog(Exception exp) { File f = getFile(); if (f != null) { try { FileWriter fw = new FileWriter(f , true); PrintWriter pw = new PrintWriter(fw); pw.append("\n"); exp.printStackTrace(pw); pw.flush(); pw.close(); fw.close(); } catch (IOException e) { print("writeLog error, " + e.getMessage()); } } else { print("writeLog error, due to the file dir is error"); } } /** * 获取文件 * @return */ private static final File getFile() { if ("".equals(LOG_FILE_DIR)) { return null; } synchronized (LogUtil.class) { if (!IF_START_NEWLOG) { File currFile = new File(CURRENT_LOG_NAME); if (currFile.length() >= LOG_MAX_SIZE) { IF_START_NEWLOG = true; return getFile(); } return currFile; } File f = new File(LOG_FILE_DIR); if (!f.exists()) { f.mkdirs(); } File file = new File(f.getAbsolutePath() + File.separator + getCurrTimeDir() + ".log"); if (!file.exists()) { try { file.createNewFile(); FILE_LOG_COUNT = 0; IF_START_NEWLOG = false; CURRENT_LOG_NAME = file.getAbsolutePath(); } catch (IOException e) { print("createFile error , " + e.getMessage()); } } else { //已经存在了 if (IF_START_NEWLOG) { FILE_LOG_COUNT ++; return new File(f.getAbsolutePath() + File.separator + getCurrTimeDir() + "_" + FILE_LOG_COUNT+ ".log"); } } return file; } } } /** * SD卡管理器 */ private static class SDcardUtil { // public static String getAbsPath() { // if (isMounted()) { // return Environment.getExternalStorageDirectory().getAbsolutePath(); // } // return ""; // } /** 获取Path*/ public static String getPath() { if (isMounted()) { return Environment.getExternalStorageDirectory().getPath(); } LogFile.print("please check if sd card is not mounted"); return ""; } /** 判断SD卡是否mounted*/ public static boolean isMounted() { return Environment.isExternalStorageEmulated(); } } }
用法介绍: 设置日志打印级别 LogUtil.LEVEL = LogUtil.W; (默认为LogUtil.I) 设置应用打印日志路径名称 LogUtil.setDefaultFilePath(context); 设置应用自定义打印日志路径名称 LogUtil.setLogFilePath("com/demo/log"); 设置同步打印记录到日志 LogUtil.setSyns(true); 设置启用一个新的LOG LogUtil.startNewLog(); 打印单行信息 LogUtil.i(msg) LogUtil.v(msg) LogUtil.w(msg) LogUtil.d(msg) LogUtil.e(msg); 打印异常信息 LogUtil.i(exp) .... ; 强制打印信息 LogUtil.print(msg); LogUtil.print(exp); ========================================================================================== 一般应用发布前要除去项目中的打印信息,因此只需要设置LogUtil.LEVEL = 10 (比LogUtil.E大即可); 对于强制打印的信息,将无法去除。 欢迎大家补充,以及指点错误之处。
相关文章推荐
- Android 日志打印工具类 可显示打印所在的方法和行号
- [置顶] Android开发之封装log打印日志的工具类,实用logutils详细代码
- android开发必备日志打印工具类
- Android开发之封装log打印日志的工具类,实用logutils详细代码
- android开发必备日志打印工具类
- android开发必备日志打印工具类
- android开发必备日志打印工具类
- android常用工具类 -- 打印log日志
- Android 日志打印工具类
- Android-日志打印工具类
- Android打印日志工具类
- Android 日志打印工具类 可显示打印所在的方法和行号
- android orhanobut logger打印那个类第几行调用log输出,在输出日志上上点击跳转到源代码
- 检查 android.mk条件如果执行,在android.mk中打印日志信息
- Android 各层中日志打印功能的应用
- android中将读回的xml inputstream打印为日志
- eclipse,android,logcat日志无法打印,真机调试。
- Android真机调试打印日志的方法
- android 错误日志打印到本地
- Android手机查看某个烦人的进程日志是哪个打印的