修复bug&更新:

1,实际使用时发现,打印中文还是有打印不全问题,经过测试发现,java里面的string.length()无论是中文还是英文,都是按照1个长度来看待的,但是as或者eclipse的logcat把中文看成2个长度,所以logcat打印中文的长度限制是2k左右(英文4k),统一把最大长度改成2048,问题解决。

2,把jumpKeyWord改成  at(注意前面有两个空格),eclipse就可以跳转了

概述

安卓开发中,日志打印log在调试的时候基本都会用到,像这种使用比较频繁的方法应该尽量去简化它,最近发现有个比较有名的打印框架Logger,可以定位打印方法的位置并且显示的样式也挺漂亮的,不过我希望显示上能更简洁些,但是源码写的有点复杂,改起来有点麻烦,所以自己写了一个,就一个类。

需求

1,文本打印,异常打印,json格式化打印
2,可以定位打印方法的位置,可以点击跳转到调用打印的位置
2,解决logcat打印不全问题(logcat打印的文本超过4k左右,后面的内容会被自动忽略点)
3,全局的打印开关、打印标签(默认为logtag)

主要原理

1,定位方法的位置:

原理是获取当前线程里的栈里存放方法,类名等信息:

Thread.currentThread().getStackTrace();

不多说,这个东西还有一个用处,就是项目上线后用来记录客户的的错误信息

跳转的话,打印文本中符合 . (XX.java:YY)规范就可以点击跳转,XX是类名,YY是行号,注意括号前面有个点,有个点才能被studio识别,eclipse的是“at ” 

2,打印不全:

文本长度超过3500,分多条log打印

3,json格式化:

JSONObject和JSONArray内部有个缩进的地方tostring(int indentSpaces),

indentSpaces的取值有哪些没找到,logger中的是2,这里也定为2

主要代码

package com.myutils.l;

import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * @author zengmiaosen
 * @email 1510809124@qq.com
 * @git 
 * @CreateDate 2016/9/22 1:39
 * @Descrition 日志打印
 */
public class L {

    private static boolean isLogger =true;

    // 打印标签
    private static String logtag = "logtag";

    /**
     * 点击跳转到类的关键字  eclipse是 at android studio是☞.(任意文字加.)
     */
    private static String jumpKeyWord = "  ☞. ";
    /**
     * logcat在实现上对于message的内存分配大概,2k左右, 所以超过的内容都直接被丢弃,设置文本长度超过LOG_MAXLENGTH分多条打印
     */
    private final static int LOG_MAXLENGTH = 2048;

    // 记录上次的logLocation
    private static String lastLogMethod = "";



    /**
     * 打印文本
     *
     * @param text
     */
    public static void i(String text) {
        if (isLogger) {
            Log.i(logtag, logContent(text) + logLocation(0));
        }
    }

    public static void i(String text, int index) {
        if (isLogger) {
            Log.i(logtag, logContent(text) + logLocation(index));
        }
    }


    /**
     * 打印异常文本
     *
     * @param text
     */
    public static void e(String text) {
        if (isLogger) {
            Log.e(logtag, logContent(text) + logLocation(0));
        }
    }

    /**
     * 打印异常
     *
     * @param msg
     * @param e
     */
    public static void e(String msg, Exception e) {
        if (isLogger) {
            Log.e(logtag, msg + logLocation(0), e);
        }
    }

    /**
     * 打印json格式文本
     *
     * @param json
     */
    public static void json(String json) {
        if (isLogger) {
            json("", json);
        }
    }

    /**
     * 打印json格式文本
     *
     * @param prefix
     *            前缀文本
     * @param json
     */
    public static void json(String prefix, String json) {
        if (isLogger) {
            String text = prefix + fomatJson(json);
            Log.i(logtag, logContent(text) + logLocation(0));
        }
    }

    /**
     * 打印内容
     *
     * @param text
     * @return
     */
    private static String logContent(String text) {
        if (text.length() < 50) {// 内容长度不超过50,前面加空格加到50
            int minLeng = 50 - text.length();
            // Log.i(logtag, "leng========" + leng + "   " + text.length());
            if (minLeng > 0) {
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < minLeng; i++) {
                    stringBuilder.append(" ");
                }
                text = text + stringBuilder.toString();
            }
        } else if (text.length() > LOG_MAXLENGTH) {// 内容超过logcat单条打印上限,分批打印
            //Log.i(logtag, "text长度=========" + text.length());
            int logTime = text.length() / LOG_MAXLENGTH;
            for (int i = 0; i < logTime; i++) {
                String leng = text.substring(i * LOG_MAXLENGTH, (i + 1)
                        * LOG_MAXLENGTH);
                // 提示
                if (i == 0) {
                    Log.i(logtag, "打印分" + logTime + "条显示 :" + leng);
                } else {
                    Log.i(logtag, "接上条↑" + leng);
                }

            }
            text = "接上条↑"
                    + text.substring(logTime * LOG_MAXLENGTH, text.length());
        }
        return text;
    }

    /**
     * 定位打印的方法
     *
     * @return
     */
    private static StringBuilder logLocation(int index) {
        StackTraceElement logStackTrace = getLogStackTrace(index);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(jumpKeyWord).append(" (").append(logStackTrace.getFileName())
                .append(":").append(logStackTrace.getLineNumber() + ")");
        // Log.i(logtag, "leng========" + stringBuilder + "   " +
        // lastLogMethod);
        if (stringBuilder.toString().equals(lastLogMethod)) {
            stringBuilder = new StringBuilder("");
        } else {
            lastLogMethod = stringBuilder.toString();
        }

        return stringBuilder;
    }

    /**
     * json格式化
     *
     * @param jsonStr
     * @return
     */
    private static String fomatJson(String jsonStr) {
        try {
            jsonStr = jsonStr.trim();
            if (jsonStr.startsWith("{")) {
                JSONObject jsonObject = new JSONObject(jsonStr);
                return jsonObject.toString(2);
            }
            if (jsonStr.startsWith("[")) {
                JSONArray jsonArray = new JSONArray(jsonStr);
                return jsonArray.toString(2);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return "Json格式有误: " + jsonStr;
    }

    /**
     * 获取调用打印方法的栈 index 调用打印i/e/json的index为0
     *
     * @return
     */
    private static StackTraceElement getLogStackTrace(int index) {
        StackTraceElement logTackTraces = null;
        StackTraceElement[] stackTraces = Thread.currentThread()
                .getStackTrace();
        // Log.i(logtag, JSONSerializer.toJson(stackTraces));
        for (int i = 0; i < stackTraces.length; i++) {
            StackTraceElement stackTrace = stackTraces[i];
            if (stackTrace.getClassName().equals(L.class.getName())) {
                // getLogStackTrace--logLocation--i/e/json--方法栈,所以调用打印方法栈的位置是当前方法栈后的第3个
                logTackTraces = stackTraces[i + 3 + index];
                i = stackTraces.length;
            }
        }
        return logTackTraces;
    }

    public static void setLogtag(String logtag) {
        L.logtag = logtag;
    }

    public static void setIsLog(boolean isLogger) {
        L.isLogger = isLogger;
    }


}

使用方法

初始化:

L.setIsLog(true);
 L.setLogtag("logtag");

调用:

L.i("打印文本----");
 L.e("出错了!");
 L.e("出错了!", new RuntimeException("啊啊"));
 L.json(getJson(1).toString());
 L.json("返回的json数据== ", getJson(1).toString());
 L.json("返回的json数据比较长== ", getLongJson(100));

效果:

Android怎么打印堆栈日志 android 日志打印_json格式


Android怎么打印堆栈日志 android 日志打印_json_02


Android怎么打印堆栈日志 android 日志打印_json格式_03

studio设置

Android怎么打印堆栈日志 android 日志打印_Android怎么打印堆栈日志_04


Android怎么打印堆栈日志 android 日志打印_json格式_05