羊皮书APP (Android版)开发系列(二)日志工具类

在App开发过程中,很重要的一个调试工具就是日志的打印,Android系统自带的日志打印文件,看起来并不是很直观。这里我们自己对原生Android 日志做一个封装,方便我们使用。

  • 为了更方便,更简洁,将日志文件工具命名为L.java,代码如下:
package cn.studyou.parchment.log;

import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
/**
 * 基本功能:记录日志
 * 创建:王杰
 * 创建时间:16/3/7
 * 邮箱:w489657152@gmail.com
 */
public class L {

    private static boolean IS_SHOW_LOG = true;

    private static final String DEFAULT_MESSAGE = "execute";
    private static final String LINE_SEPARATOR = System.getProperty("line.separator");
    private static final int JSON_INDENT = 4;

    private static final int V = 0x1;
    private static final int D = 0x2;
    private static final int I = 0x3;
    private static final int W = 0x4;
    private static final int E = 0x5;
    private static final int A = 0x6;
    private static final int JSON = 0x7;
    private static final int FILE = 0x8;

    public static void init(boolean isShowLog) {
        IS_SHOW_LOG = isShowLog;
    }

    public static void v() {
        printLog(V, null, DEFAULT_MESSAGE);
    }

    public static void v(Object msg) {
        printLog(V, null, msg);
    }

    public static void v(String tag, String msg) {
        printLog(V, tag, msg);
    }

    public static void d() {
        printLog(D, null, DEFAULT_MESSAGE);
    }

    public static void d(Object msg) {
        printLog(D, null, msg);
    }

    public static void d(String tag, Object msg) {
        printLog(D, tag, msg);
    }

    public static void i() {
        printLog(I, null, DEFAULT_MESSAGE);
    }

    public static void i(Object msg) {
        printLog(I, null, msg);
    }

    public static void i(String tag, Object msg) {
        printLog(I, tag, msg);
    }

    public static void w() {
        printLog(W, null, DEFAULT_MESSAGE);
    }

    public static void w(Object msg) {
        printLog(W, null, msg);
    }

    public static void w(String tag, Object msg) {
        printLog(W, tag, msg);
    }

    public static void e() {
        printLog(E, null, DEFAULT_MESSAGE);
    }

    public static void e(Object msg) {
        printLog(E, null, msg);
    }

    public static void e(String tag, Object msg) {
        printLog(E, tag, msg);
    }

    public static void a() {
        printLog(A, null, DEFAULT_MESSAGE);
    }

    public static void a(Object msg) {
        printLog(A, null, msg);
    }

    public static void a(String tag, Object msg) {
        printLog(A, tag, msg);
    }

    public static void json(String jsonFormat) {
        printLog(JSON, null, jsonFormat);
    }

    public static void json(String tag, String jsonFormat) {
        printLog(JSON, tag, jsonFormat);
    }

    public static void file(File targetDirectory, Object msg) {
        printFile(null, targetDirectory, null, msg);
    }

    public static void file(String tag, File targetDirectory, Object msg) {
        printFile(tag, targetDirectory, null, msg);
    }

    public static void file(String tag, File targetDirectory, String fileName, Object msg) {
        printFile(tag, targetDirectory, fileName, msg);
    }

    private static void printLog(int type, String tagStr, Object objectMsg) {

        if (!IS_SHOW_LOG) {
            return;
        }

        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

        int index = 4;
        String className = stackTrace[index].getFileName();
        String methodName = stackTrace[index].getMethodName();
        int lineNumber = stackTrace[index].getLineNumber();

        String tag = (tagStr == null ? className : tagStr);

        String methodNameShort = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("[ (").append(className).append(":").append(lineNumber).append(")#").append(methodNameShort).append(" ] ");
        String msg = (objectMsg == null) ? "Log with null Object" : objectMsg.toString();

        if (msg != null && type != JSON) {
            stringBuilder.append(msg);
        }

        String logStr = stringBuilder.toString();

        switch (type) {
            case V:
            case D:
            case I:
            case W:
            case E:
            case A:
                printLog(type, tag, logStr);
                break;
            case JSON: {
                if (TextUtils.isEmpty(msg)) {
                    Log.e(tag, "Empty or Null json content");
                    return;
                }
                printJson(tag, msg, logStr);
            }
            break;
        }

    }


    private static void printLog(int type, String tag, String logStr) {
        switch (type) {
            case V:
                Log.v(tag, logStr);
                break;
            case D:
                Log.d(tag, logStr);
                break;
            case I:
                Log.i(tag, logStr);
                break;
            case W:
                Log.w(tag, logStr);
                break;
            case E:
                Log.e(tag, logStr);
                break;
            case A:
                Log.wtf(tag, logStr);
                break;
        }
    }

    private static void printJson(String tag, String msg, String logStr) {

        String message = null;

        try {
            if (msg.startsWith("{")) {
                JSONObject jsonObject = new JSONObject(msg);
                message = jsonObject.toString(JSON_INDENT);
            } else if (msg.startsWith("[")) {
                JSONArray jsonArray = new JSONArray(msg);
                message = jsonArray.toString(JSON_INDENT);
            }
        } catch (JSONException e) {
            e(tag, e.getCause().getMessage() + "\n" + msg);
            return;
        }

        printLine(tag, true);
        message = logStr + LINE_SEPARATOR + message;
        String[] lines = message.split(LINE_SEPARATOR);
        StringBuilder jsonContent = new StringBuilder();
        for (String line : lines) {
            jsonContent.append("║ ").append(line).append(LINE_SEPARATOR);
        }
        Log.d(tag, jsonContent.toString());
        printLine(tag, false);
    }

    private static void printFile(String tag, File targetDirectory, String fileName, Object objectMsg) {

        if (!IS_SHOW_LOG) {
            return;
        }

        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

        int index = 4;
        String className = stackTrace[index].getFileName();
        String methodName = stackTrace[index].getMethodName();
        int lineNumber = stackTrace[index].getLineNumber();

        tag = (tag == null ? className : tag);

        String methodNameShort = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("[ (").append(className).append(":").append(lineNumber).append(")#").append(methodNameShort).append(" ] ");
        String msg = (objectMsg == null) ? "Log with null Object" : objectMsg.toString();

        String headString = stringBuilder.toString();

        if (msg != null) {
            msg = headString + msg;
        }

        fileName = (fileName == null) ? FileHelper.getFileName() : fileName;
        if (FileHelper.save(targetDirectory, fileName, msg)) {
            Log.d(tag, headString + " save log success ! location is >>>" + targetDirectory.getAbsolutePath() + "/" + fileName);
        } else {
            Log.e(tag, headString + "save log fails !");
        }
    }

    private static void printLine(String tag, boolean isTop) {
        if (isTop) {
            Log.d(tag, "╔═══════════════════════════════════════════════════════════════════════════════════════");
        } else {
            Log.d(tag, "╚═══════════════════════════════════════════════════════════════════════════════════════");
        }
    }

}
  • FileHelper.java 代码如下:
package cn.studyou.parchment.log;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Random;

/**
 * 基本功能:FileHelper
 * 创建:王杰
 * 创建时间:16/3/7
 * 邮箱:w489657152@gmail.com
 */
public class FileHelper {

    public static boolean save(File dic, String fileName, String msg) {

        File file = new File(dic, fileName);

        try {
            OutputStream outputStream = new FileOutputStream(file);
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
            outputStreamWriter.write(msg);
            outputStreamWriter.flush();
            outputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    public static String getFileName() {
        Random random = new Random();
        StringBuilder stringBuilder = new StringBuilder("KLog_");
        stringBuilder.append(Long.toString(System.currentTimeMillis()+random.nextInt(10000)).substring(4));
        stringBuilder.append(".txt");
        return stringBuilder.toString();
    }

}

这个日志工具只有以上两个文件,那么我们如何使用这个日志工具呢?很简答。

  • 首先在APP的Application文件中设置debug开关:
public static final boolean DEVELOPER_MODE = true;
  • 其次在OnCreate方法中进行初始化:
 @Override
    public void onCreate() {
        super.onCreate();
        //初始化日志工具
        L.init(DEVELOPER_MODE);
    }
  • 到这里初始化就完成了,在我们的java文件中使用这个日志工具L:
L.e("First start!");
L.i("First start!");
L.a("First start!");
  • 控制台显示结果:
03-07 13:37:59.470 14633-14633/cn.studyou.parchment E/StartUpActivity.java: [ (StartUpActivity.java:24)#OnCreate ] First start!
03-07 13:37:59.470 14633-14633/cn.studyou.parchment I/StartUpActivity.java: [ (StartUpActivity.java:26)#OnCreate ] First start!
03-07 13:37:59.470 14633-14633/cn.studyou.parchment A/StartUpActivity.java: [ (StartUpActivity.java:27)#OnCreate ] First start!
  • 点击控制台超链接StartUpActivity.java:24即可直接定位到日志的具体位置。是不是很简单呢?赶紧试试吧!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码匠的流水账

聊聊storm的IEventLogger

storm-2.0.0/storm-client/src/jvm/org/apache/storm/metric/IEventLogger.java

882
来自专栏码匠的流水账

聊聊kafka 0.8 ConsumerFetcherManager的MaxLag指标

本文主要研究一下kafka0.8.2.2版本中ConsumerFetcherManager的MaxLag指标的统计。

1021
来自专栏后端沉思录

自定义钉钉机器人报警

按照钉钉的文档来开发,创建机器人后,即可获取Webhook地址,整个过程还是很简单的,以上只是提供了一个思路.

3532
来自专栏小白鼠

【DUBBO】 Schema解析Spring扩展机制集成Spring

dubbo是如何做到与spring集成的?这都依赖于Spring提供的XML Schema可扩展机制,用户可以自定义XML Schema文件,并自定义XML B...

1793
来自专栏技术栈大杂烩

Python的Sequence切片下标问题

在python中, 切片是一个经常会使用到的语法, 不管是元组, 列表还是字符串, 一般语法就是:

1152
来自专栏Java学习网

Java实现把整数转换为英语单词的方法,实用代码

一个非负整数转换为英文单词表示。 例如: 123 -> "One Hundred Twenty Three" 12345 -> "Twelve Thousand...

2489
来自专栏Hellovass 的博客

魔改 TypeAdapterFactory

感慨:Retrofit2 虽好,但是,有时候总感觉 Java 这门语言还是美中不足啊!

1761
来自专栏积累沉淀

研究MapReduce源码之实现自定义LineRecordReader完成多行读取文件内容

TextInputFormat是Hadoop默认的数据输入格式,但是它只能一行一行的读记录,如果要读取多行怎么办? 很简单 自己写一个输入格式,然后写一个对...

2089
来自专栏函数式编程语言及工具

SDP(6):分布式数据库运算环境- Cassandra-Engine

    现代信息系统应该是避不开大数据处理的。作为一个通用的系统集成工具也必须具备大数据存储和读取能力。cassandra是一种分布式的数据库,具备了分布式数据...

3354
来自专栏码匠的流水账

聊聊flink的CheckpointScheduler

flink-runtime_2.11-1.7.0-sources.jar!/org/apache/flink/runtime/checkpoint/Checkp...

1383

扫码关注云+社区

领取腾讯云代金券