引用别人的话“我们不重复造轮子不表示我们不需要知道轮子该怎么造及如何更好的造!”
KyLog应该是最简单的,最适合像我这种刚刚看别人源码的同学。项目github地址:https://github.com/kyosky110/Kylog
(1)怎么打印出className,行数这些信息的?
上图的信息显示,该打印语句出现在MainActivity.java这个文件里面的onCreate()方法里面,MainActivity的39行代码。这些是怎么打印出来的?途中蓝色的代码是可以点击,点击后光标跳转到指定行数,这个又是怎么实现的呢?
答案:
使用Thread.currentThread().getStackTrace()这个方法来获取我们所需要的信息。
由源码可以得知每个StackTraceElement里面有methodName,fileName,lineNumber,declaringClass的获取方法
//由于是在主函数里面获取StackTraceElement,所以只用取第二个就可以了 StackTraceElement element = Thread.currentThread().getStackTrace()[2]; System.out.println(element); System.out.println("className: " + element.getClassName());//类名 System.out.println("filesName: " + element.getFileName());//文件名 System.out.println("methodName: " + element.getMethodName());//方法名 System.out.println("lineNumber: " + element.getLineNumber());//调用的位置
输出结果:
/System.out: stack dalvik.system.VMStack.getThreadStackTrace(Native Method)
/System.out: stack java.lang.Thread.getStackTrace(Thread.java:579)
/System.out: stack com.sky.yunlv.yunlv_android.util.CommUtil.getStack(CommUtil.java:10)
/System.out: stack com.sky.yunlv.yunlv_android.MainActivity.onCreate(MainActivity.java:121)
/System.out: stack android.app.Activity.performCreate(Activity.java:5133)
KyLog里面单独一个方法来整理这些信息:
private String[] generateValues(StackTraceElement element){ String[] values = new String[2]; StackTraceElement traceElement = element; StringBuilder sb = new StringBuilder(); String className = traceElement.getClassName(); String fileName = traceElement.getFileName(); sb.append(className.substring(className.lastIndexOf(".") + 1)).append(".").append(traceElement.getMethodName()) .append(" (").append(fileName).append(":").append(traceElement.getLineNumber()) .append(") "); String tag = sb.toString(); values[0] = tag; values[1] = fileName; return values; }
String[] values = generateValues(element);
String tag = values[0];
String fileName = values[1];
返回的tag就是这种类型MainActivity.onCreate(MainActivity.java:39) ,fileName就是MainActivity.java.
为什么可以点进去,因为打印的MainActivity.java:39这两边加了括号(),如果不加括号就不会出现蓝色,也不可点击,为什么呢,我现在不知道。
(2)怎么打印对象的,如图
利用java反射机制打印,可参考
private String LogObject(Object object){
Class myClass=object.getClass();
//获取所有的属性,包括private属性 ,需要权限 field.setAccessible(true);
Field[] fields = myClass.getDeclaredFields();
StringBuffer buffer = new StringBuffer();
buffer.append( myClass.getSimpleName()+"{ ");
for (Field field : fields) {
field.setAccessible(true);
Object value=null;
try {
value = field.get(object);
} catch (IllegalAccessException e) {
value=e;
}
buffer.append(field.getName()+ "="+(value == null ? "null" : value.toString())+",");//属性的名字
}
}
return builder.replace(builder.length() - 2, builder.length() - 1, " }").toString();//把最后一个“,”变成“}”
}
(3)怎么打印字符串的json数据,像下图的样式
代码如下:
private String LogJson(String json){ try { if (json.startsWith("{")){ JSONObject jsonObject = new JSONObject(json); json = jsonObject.toString(4); return json; }else if (json.startsWith("[")){ JSONArray array = new JSONArray(json); json = array.toString(4); return json; } } catch (JSONException e) { e.printStackTrace(); } return null; }能打印成这种样式,主要是jsonObject.toString(4)这个方法的作用,4是缩进的字符数。
(4)怎么打印map对象,效果如下图:
代码:
private String LogMap(Map object){
Map<Object,Object> map = (Map<Object, Object>) object;
Set<Object> keys = map.keySet();
if (keys.size() > 0) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" {\n");
for (Object key : keys){
stringBuilder.append(" ")
.append(String.format("[%s -> %s]\n",key.toString(),map.get(key)));
}
stringBuilder.append("}\n");
return stringBuilder.toString();
}else {
Log.d("",null);
}
return null;
}
关键句:Set<Object> keys = map.keySet();
(5)怎么打印List,效果图如下图:
代码:
private String LogList(Collection collection) { if (collection != null && !collection.isEmpty()) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(collection.getClass().getSimpleName()).append(" size = ") .append(collection.size()).append("[\n"); Iterator<Object> iterator = collection.iterator(); int index = 0; while (iterator.hasNext()) { String itemString = " [%d]:%s%s"; Object item = iterator.next(); stringBuilder.append(String.format(itemString, index, item.toString(), index++ < collection.size() - 1 ? ",\n" : "\n")); } stringBuilder.append(" ]\n"); return stringBuilder.toString(); } else { return null; } }
所有实现Collection接口容器类都有一个iterator方法用以返回一个实现iterator接口对象。 iterator对象称迭代器,方便对实现对容器内元素的遍历操作。就是通过遍历操作来得到每一条数据。
KyLog大致就是上面的信息啦,因为封装要考虑很多,所以上面的代码是为了更好的描述。