修复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));
效果:
studio设置