日志相关→LogUtils

   
  import android.os.Environment;
  import android.support.annotation.IntDef;
  import android.util.Log;
   
  import org.json.JSONArray;
  import org.json.JSONException;
  import org.json.JSONObject;
   
  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.StringReader;
  import java.io.StringWriter;
  import java.lang.annotation.Retention;
  import java.lang.annotation.RetentionPolicy;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import java.util.Formatter;
  import java.util.Locale;
   
  import javax.xml.transform.OutputKeys;
  import javax.xml.transform.Source;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerFactory;
  import javax.xml.transform.stream.StreamResult;
  import javax.xml.transform.stream.StreamSource;
   
  /**
  * <pre>
  * author: Blankj
  * blog : http://blankj.com
  * time : 2016/9/21
  * desc : 日志相关工具类
  * </pre>
  */
  public final class LogUtils {
   
  private LogUtils() {
  throw new UnsupportedOperationException("u can't instantiate me...");
  }
   
  public static final int V = 0x01;
  public static final int D = 0x02;
  public static final int I = 0x04;
  public static final int W = 0x08;
  public static final int E = 0x10;
  public static final int A = 0x20;
   
  @IntDef({V, D, I, W, E, A})
  @Retention(RetentionPolicy.SOURCE)
  public @interface TYPE {
  }
   
  private static final int FILE = 0xF1;
  private static final int JSON = 0xF2;
  private static final int XML = 0xF4;
   
  private static String dir; // log存储目录
  private static boolean sLogSwitch = true; // log总开关
  private static String sGlobalTag = null; // log标签
  private static boolean sTagIsSpace = true; // log标签是否为空白
  private static boolean sLog2FileSwitch = false;// log写入文件开关
  private static boolean sLogBorderSwitch = true; // log边框开关
  private static int sLogFilter = V; // log过滤器
   
  private static final String TOP_BORDER = "╔═══════════════════════════════════════════════════════════════════════════════════════════════════";
  private static final String LEFT_BORDER = "";
  private static final String BOTTOM_BORDER = "╚═══════════════════════════════════════════════════════════════════════════════════════════════════";
  private static final String LINE_SEPARATOR = System.getProperty("line.separator");
   
  private static final int MAX_LEN = 4000;
  private static final String NULL_TIPS = "Log with null object.";
  private static final String NULL = "null";
  private static final String ARGS = "args";
   
  public static class Builder {
   
  public Builder() {
  if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
  dir = Utils.getContext().getExternalCacheDir() + File.separator + "log" + File.separator;
  } else {
  dir = Utils.getContext().getCacheDir() + File.separator + "log" + File.separator;
  }
  }
   
  public Builder setGlobalTag(String tag) {
  if (!isSpace(tag)) {
  LogUtils.sGlobalTag = tag;
  sTagIsSpace = false;
  } else {
  LogUtils.sGlobalTag = "";
  sTagIsSpace = true;
  }
  return this;
  }
   
  public Builder setLogSwitch(boolean logSwitch) {
  LogUtils.sLogSwitch = logSwitch;
  return this;
  }
   
  public Builder setLog2FileSwitch(boolean log2FileSwitch) {
  LogUtils.sLog2FileSwitch = log2FileSwitch;
  return this;
  }
   
  public Builder setBorderSwitch(boolean borderSwitch) {
  LogUtils.sLogBorderSwitch = borderSwitch;
  return this;
  }
   
  public Builder setLogFilter(@TYPE int logFilter) {
  LogUtils.sLogFilter = logFilter;
  return this;
  }
  }
   
  public static void v(Object contents) {
  log(V, sGlobalTag, contents);
  }
   
  public static void v(String tag, Object... contents) {
  log(V, tag, contents);
  }
   
  public static void d(Object contents) {
  log(D, sGlobalTag, contents);
  }
   
  public static void d(String tag, Object... contents) {
  log(D, tag, contents);
  }
   
  public static void i(Object contents) {
  log(I, sGlobalTag, contents);
  }
   
  public static void i(String tag, Object... contents) {
  log(I, tag, contents);
  }
   
  public static void w(Object contents) {
  log(W, sGlobalTag, contents);
  }
   
  public static void w(String tag, Object... contents) {
  log(W, tag, contents);
  }
   
  public static void e(Object contents) {
  log(E, sGlobalTag, contents);
  }
   
  public static void e(String tag, Object... contents) {
  log(E, tag, contents);
  }
   
  public static void a(Object contents) {
  log(A, sGlobalTag, contents);
  }
   
  public static void a(String tag, Object... contents) {
  log(A, tag, contents);
  }
   
  public static void file(Object contents) {
  log(FILE, sGlobalTag, contents);
  }
   
  public static void file(String tag, Object contents) {
  log(FILE, tag, contents);
  }
   
  public static void json(String contents) {
  log(JSON, sGlobalTag, contents);
  }
   
  public static void json(String tag, String contents) {
  log(JSON, tag, contents);
  }
   
  public static void xml(String contents) {
  log(XML, sGlobalTag, contents);
  }
   
  public static void xml(String tag, String contents) {
  log(XML, tag, contents);
  }
   
  private static void log(int type, String tag, Object... contents) {
  if (!sLogSwitch) return;
  final String[] processContents = processContents(type, tag, contents);
  tag = processContents[0];
  String msg = processContents[1];
  switch (type) {
  case V:
  case D:
  case I:
  case W:
  case E:
  case A:
  if (V == sLogFilter || type >= sLogFilter) {
  printLog(type, tag, msg);
  }
  if (sLog2FileSwitch) {
  print2File(tag, msg);
  }
  break;
  case FILE:
  print2File(tag, msg);
  break;
  case JSON:
  printLog(D, tag, msg);
  break;
  case XML:
  printLog(D, tag, msg);
  break;
  }
   
  }
   
  private static String[] processContents(int type, String tag, Object... contents) {
  StackTraceElement targetElement = Thread.currentThread().getStackTrace()[5];
  String className = targetElement.getClassName();
  String[] classNameInfo = className.split("\\.");
  if (classNameInfo.length > 0) {
  className = classNameInfo[classNameInfo.length - 1];
  }
  if (className.contains("$")) {
  className = className.split("\\$")[0];
  }
  if (!sTagIsSpace) {// 如果全局tag不为空,那就用全局tag
  tag = sGlobalTag;
  } else {// 全局tag为空时,如果传入的tag为空那就显示类名,否则显示tag
  tag = isSpace(tag) ? className : tag;
  }
   
  String head = new Formatter()
  .format("Thread: %s, %s(%s.java:%d)" + LINE_SEPARATOR,
  Thread.currentThread().getName(),
  targetElement.getMethodName(),
  className,
  targetElement.getLineNumber())
  .toString();
  String msg = NULL_TIPS;
  if (contents != null) {
  if (contents.length == 1) {
  Object object = contents[0];
  msg = object == null ? NULL : object.toString();
  if (type == JSON) {
  msg = formatJson(msg);
  } else if (type == XML) {
  msg = formatXml(msg);
  }
  } else {
  StringBuilder sb = new StringBuilder();
  for (int i = 0, len = contents.length; i < len; ++i) {
  Object content = contents[i];
  sb.append(ARGS)
  .append("[")
  .append(i)
  .append("]")
  .append(" = ")
  .append(content == null ? NULL : content.toString())
  .append(LINE_SEPARATOR);
  }
  msg = sb.toString();
  }
  }
  if (sLogBorderSwitch) {
  StringBuilder sb = new StringBuilder();
  String[] lines = msg.split(LINE_SEPARATOR);
  for (String line : lines) {
  sb.append(LEFT_BORDER).append(line).append(LINE_SEPARATOR);
  }
  msg = sb.toString();
  }
  return new String[]{tag, head + msg};
  }
   
  private static String formatJson(String json) {
  try {
  if (json.startsWith("{")) {
  json = new JSONObject(json).toString(4);
  } else if (json.startsWith("[")) {
  json = new JSONArray(json).toString(4);
  }
  } catch (JSONException e) {
  e.printStackTrace();
  }
  return json;
  }
   
  private static String formatXml(String xml) {
  try {
  Source xmlInput = new StreamSource(new StringReader(xml));
  StreamResult xmlOutput = new StreamResult(new StringWriter());
  Transformer transformer = TransformerFactory.newInstance().newTransformer();
  transformer.setOutputProperty(OutputKeys.INDENT, "yes");
  transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
  transformer.transform(xmlInput, xmlOutput);
  xml = xmlOutput.getWriter().toString().replaceFirst(">", ">" + LINE_SEPARATOR);
  } catch (Exception e) {
  e.printStackTrace();
  }
  return xml;
  }
   
  private static void printLog(int type, String tag, String msg) {
  if (sLogBorderSwitch) printBorder(type, tag, true);
  int len = msg.length();
  int countOfSub = len / MAX_LEN;
  if (countOfSub > 0) {
  int index = 0;
  String sub;
  for (int i = 0; i < countOfSub; i++) {
  sub = msg.substring(index, index + MAX_LEN);
  printSubLog(type, tag, sub);
  index += MAX_LEN;
  }
  printSubLog(type, tag, msg.substring(index, len));
  } else {
  printSubLog(type, tag, msg);
  }
  if (sLogBorderSwitch) printBorder(type, tag, false);
  }
   
  private static void printSubLog(final int type, final String tag, String msg) {
  if (sLogBorderSwitch) msg = LEFT_BORDER + msg;
  switch (type) {
  case V:
  Log.v(tag, msg);
  break;
  case D:
  Log.d(tag, msg);
  break;
  case I:
  Log.i(tag, msg);
  break;
  case W:
  Log.w(tag, msg);
  break;
  case E:
  Log.e(tag, msg);
  break;
  case A:
  Log.wtf(tag, msg);
  break;
  }
  }
   
  private static void printBorder(int type, String tag, boolean isTop) {
  String border = isTop ? TOP_BORDER : BOTTOM_BORDER;
  switch (type) {
  case V:
  Log.v(tag, border);
  break;
  case D:
  Log.d(tag, border);
  break;
  case I:
  Log.i(tag, border);
  break;
  case W:
  Log.w(tag, border);
  break;
  case E:
  Log.e(tag, border);
  break;
  case A:
  Log.wtf(tag, border);
  break;
  }
  }
   
  private synchronized static void print2File(final String tag, final String msg) {
  Date now = new Date();
  String date = new SimpleDateFormat("MM-dd", Locale.getDefault()).format(now);
  final String fullPath = dir + date + ".txt";
  if (!createOrExistsFile(fullPath)) {
  Log.e(tag, "log to " + fullPath + " failed!");
  return;
  }
  String time = new SimpleDateFormat("MM-dd HH:mm:ss.SSS ", Locale.getDefault()).format(now);
  StringBuilder sb = new StringBuilder();
  if (sLogBorderSwitch) sb.append(TOP_BORDER).append(LINE_SEPARATOR);
  sb.append(time)
  .append(tag)
  .append(": ")
  .append(msg)
  .append(LINE_SEPARATOR);
  if (sLogBorderSwitch) sb.append(BOTTOM_BORDER).append(LINE_SEPARATOR);
  final String dateLogContent = sb.toString();
  new Thread(new Runnable() {
  @Override
  public void run() {
  BufferedWriter bw = null;
  try {
  bw = new BufferedWriter(new FileWriter(fullPath, true));
  bw.write(dateLogContent);
  Log.d(tag, "log to " + fullPath + " success!");
  } catch (IOException e) {
  e.printStackTrace();
  Log.e(tag, "log to " + fullPath + " failed!");
  } finally {
  try {
  if (bw != null) {
  bw.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
  }
  }).start();
  }
   
  private static boolean createOrExistsFile(String filePath) {
  return createOrExistsFile(isSpace(filePath) ? null : new File(filePath));
  }
   
  private static boolean createOrExistsFile(File file) {
  if (file == null) return false;
  if (file.exists()) return file.isFile();
  if (!createOrExistsDir(file.getParentFile())) return false;
  try {
  return file.createNewFile();
  } catch (IOException e) {
  e.printStackTrace();
  return false;
  }
  }
   
  private static boolean createOrExistsDir(File file) {
  return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());
  }
   
  private static boolean isSpace(String s) {
  if (s == null) return true;
  for (int i = 0, len = s.length(); i < len; ++i) {
  if (!Character.isWhitespace(s.charAt(i))) {
  return false;
  }
  }
  return true;
  }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值