Android KLog源代码分析
Android KLog源代码分析
- Android KLog源代码分析
- 代码结构
- 详细分析
- BaseLog
- FileLog
- JsonLog
- XmlLog
- 核心文件KLogjava分析
- 遇到的问题
一直使用这个库。但没有细致研究。今天就来研究一下。该库的地址:
KLog,在这里先感谢下作者。棒棒哒!
代码结构
整个代码的结构非常easy。例如以下:
libraryklogBaseLog.javaFileLog.javaJsonLog.javaXmlLog.javaKLog.javaKLogUtil.java
共六个文件:
- BaseLog.java,支持主要的log打印
- FileLog.java。支持以文件的形式保存log
- JsonLog.java,支持打印json对象和json数组
- XmlLog.java,支持打印Xml形式的log
详细分析
BaseLog
两个方法:
public class BaseLog {private static final int MAX_LENGTH = 4000;public static void printDefault(int type, String tag, String msg) {int index = 0;int length = msg.length();int countOfSub = length / MAX_LENGTH;if (countOfSub > 0) {// 超过指定长度,粉刺打印。这样就避免了系统默认的log长度限制了for (int i = 0; i < countOfSub; i++) {String sub = msg.substring(index, index + MAX_LENGTH);printSub(type, tag, sub);index += MAX_LENGTH;}printSub(type, tag, msg.substring(index, length));// 打印余数部分} else {printSub(type, tag, msg);}}private static void printSub(int type, String tag, String sub) {switch (type) {case KLog.V:Log.v(tag, sub);break;case KLog.D:Log.d(tag, sub);break;case KLog.I:Log.i(tag, sub);break;case KLog.W:Log.w(tag, sub);break;case KLog.E:Log.e(tag, sub);break;case KLog.A:Log.wtf(tag, sub);break;}}}
这里突破了android系统的log字数限制,事实上就是超过字数限制后。採用分次打印的方法来打印,其它代码不做分析,比較简单。
FileLog
三个方法
public class FileLog {private static final String FILE_PREFIX = "KLog_";private static final String FILE_FORMAT = ".log";/*** @param tag log tag* @param targetDirectory log file save dir* @param fileName log file name* @param headString log file 文件头* @param msg log file log内容主体*/public static void printFile(String tag, File targetDirectory, @Nullable String fileName, String headString, String msg) {fileName = (fileName == null) ? getFileName() : fileName;if (save(targetDirectory, fileName, msg)) {Log.d(tag, headString + " save log success ! location is >>>" + targetDirectory.getAbsolutePath() + "/" + fileName);} else {Log.e(tag, headString + "save log fails !");}}/*** @param dic log file save dir* @param fileName og file name* @param msg log file log内容主体* @return true if save success*/private static boolean save(File dic, @NonNull 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();return true;} catch (FileNotFoundException e) {e.printStackTrace();return false;} catch (UnsupportedEncodingException e) {e.printStackTrace();return false;} catch (IOException e) {e.printStackTrace();return false;} catch (Exception e) {e.printStackTrace();return false;}}/*** 当未设置文件名称时,随机生成一个文件名称** @return default file name*/private static String getFileName() {Random random = new Random();return FILE_PREFIX + Long.toString(System.currentTimeMillis() + random.nextInt(10000)).substring(4) + FILE_FORMAT;}}
JsonLog
JsonLog就更简单了,仅仅有一个方法(本宝宝曾经还以为Json打印会非常麻烦呢)
public class JsonLog {public static void printJson(String tag, String msg, String headString) {String message;try {if (msg.startsWith("{")) {// 处理json对象JSONObject jsonObject = new JSONObject(msg);message = jsonObject.toString(KLog.JSON_INDENT);} else if (msg.startsWith("[")) {// 处理json数组JSONArray jsonArray = new JSONArray(msg);message = jsonArray.toString(KLog.JSON_INDENT);} else {message = msg;}} catch (JSONException e) {message = msg;}KLogUtil.printLine(tag, true);// 调用格式化方法message = headString + KLog.LINE_SEPARATOR + message;String[] lines = message.split(KLog.LINE_SEPARATOR);for (String line : lines) {Log.d(tag, "║ " + line);}KLogUtil.printLine(tag, false);// 调用格式化方法}
}
XmlLog
两个方法:
public class XmlLog {/*** 打印xml** @param tag log tag* @param xml xml content* @param headString 文件头*/public static void printXml(String tag, String xml, String headString) {if (xml != null) {xml = XmlLog.formatXML(xml);xml = headString + "\n" + xml;} else {xml = headString + KLog.NULL_TIPS;}KLogUtil.printLine(tag, true);String[] lines = xml.split(KLog.LINE_SEPARATOR);for (String line : lines) {if (!KLogUtil.isEmpty(line)) {Log.d(tag, "║ " + line);}}KLogUtil.printLine(tag, false);}/*** @param inputXML xml content* @return 格式化后的xml String*/private static String formatXML(String inputXML) {try {Source xmlInput = new StreamSource(new StringReader(inputXML));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", "2");transformer.transform(xmlInput, xmlOutput);return xmlOutput.getWriter().toString().replaceFirst(">", ">\n");} catch (Exception e) {e.printStackTrace();return inputXML;}}}
细心的你会发现。不管是Json形式还是XML形式。调用的都是系统原生的方法来处理数据,因此又时候对熟悉熟悉java(或android)提供的方法还是非常方便的。哈哈。
上面用到的KLogUtil,例如以下:
public class KLogUtil {public static boolean isEmpty(String line) {return TextUtils.isEmpty(line) || line.equals("\n") || line.equals("\t") || TextUtils.isEmpty(line.trim());}public static void printLine(String tag, boolean isTop) {if (isTop) {Log.d(tag, "╔═══════════════════════════════════════════════════════════════════════════════════════");} else {Log.d(tag, "╚═══════════════════════════════════════════════════════════════════════════════════════");}}}
核心文件KLog.java分析
给方法主要提供了相似于系统log方法的不同重载,比較简单,我这里要讲的是那个获取log详细有关的类名、方法名、行号等。与之相关的就是wrapperContent这种方法了。
private static String[] wrapperContent(int stackTraceIndex, String tagStr, Object... objects) {StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();StackTraceElement targetElement = stackTrace[stackTraceIndex];String className = targetElement.getClassName();// 得到类名String[] classNameInfo = className.split("\\.");// 第一种形式if (classNameInfo.length > 0) {className = classNameInfo[classNameInfo.length - 1] + SUFFIX;}if (className.contains("$")) {//另外一种形式className = className.split("\\$")[0] + SUFFIX;}String methodName = targetElement.getMethodName();//得到方法名int lineNumber = targetElement.getLineNumber();//得到所在的行号if (lineNumber < 0) {lineNumber = 0;}String tag = (tagStr == null ? className : tagStr);if (mIsGlobalTagEmpty && TextUtils.isEmpty(tag)) {tag = TAG_DEFAULT;} else if (!mIsGlobalTagEmpty) {tag = mGlobalTag;}// 得到消息主体String msg = (objects == null) ? NULL_TIPS : getObjectsString(objects);String headString = "[ (" + className + ":" + lineNumber + ")#" + methodName + " ] ";return new String[]{tag, msg, headString};}/*** 得到消息主体** @param objects 消息对象数组* @return 消息主体字符串*/private static String getObjectsString(Object... objects) {if (objects.length > 1) {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("\n");for (int i = 0; i < objects.length; i++) {Object object = objects[i];if (object == null) {stringBuilder.append(PARAM).append("[").append(i).append("]").append(" = ").append(NULL).append("\n");} else {stringBuilder.append(PARAM).append("[").append(i).append("]").append(" = ").append(object.toString()).append("\n");}}return stringBuilder.toString();} else {Object object = objects[0];return object == null ?
NULL : object.toString(); } }
分析完成,是不是非常easy,假设你看了这个库的代码。你会认为我的分析都是多余的。
遇到的问题
在使用KLog打印json形式信息时。假设网络请求时异步的,会导致KLog.json打印的格式出现错乱。即一个结果还没有全然打印出来。里外一个就開始打印了,这个应该是并发导致的问题,之后我会在KLog的基础上对这个问题进行优化的。
转载于:https://www.cnblogs.com/claireyuancy/p/7380903.html
Android KLog源代码分析相关推荐
- android settings源代码分析(2)
通过前一篇文章 Android settings源代码分析(1) 分析,大概知道了Settings主页面是如何显示,今天主要分析"应用"这一块google是如何实现的. 应用对 ...
- Android 消息处理源代码分析(1)
Android 消息处理源代码分析(1) 在Android中,通常被使用的消息队列的代码在文件夹\sources\android-22\android\os下,涉及到下面几个类文件 Handler.j ...
- android settings源代码分析(3)
本章主要分析google settings里面存储模块的代码. 存储模块所在的fragment为: [html] view plaincopy <!-- Storage --> <h ...
- Github android客户端源代码分析之一:环境搭建
1.下载相应的包及项目,参考https://github.com/github/android/wiki/Building-From-Eclipse. 2.若需查看某些包的源文件或者javadoc,则 ...
- Android深入源代码分析理解Aidl总体调用流程(雷惊风)
2017年開始上班的第一天.老不想工作了,假期感觉还没開始就已经结束了,唉,时间就是这样,新的一年開始了,尽管非常不想干正事,没办法,必须干起来.由于后边的路还非常长,距离六十岁还非常远. 刚上班也没 ...
- android map有序存储,Android ArrayMap源代码分析
分析源码之前先来介绍一下ArrayMap的存储结构,ArrayMap数据的存储不同于HashMap和SparseArray. Java提供了HashMap,但是HashMap对于手机端而言,对空间的利 ...
- android settings源代码分析(1)
1.Android settings源码的source code路径为: kikat_4.4_CTS\packages\apps\Settings 2.settings主界面UI布局 Settings ...
- android stk 源代码分析,Android源码分析--STK
文件:StkAppService.java 函数:onCreate() STK的APP程序启动后执行的第一个函数,会调用方法: com.android.internal.telephony.gsm.s ...
- [Android]Volley源代码分析(店)应用
通过前面的谈话,我相信你有Volley有了一定的了解了原理.本章将给出一些我们的应用程序都可以在样品中直接使用,第一样品是 NetworkImageView类,事实上NetworkImageView顾 ...
- android scrcpy 源代码分析,Scrcpy投屏原理浅析-设备控制篇
起初我真的想过自己单独写一套来着,后来发现 Scrcpy与vysor是都是投屏中比较优秀的项目了,非侵入性,不需要设备单独 scrcpy启动阶段 它到底是怎么做到执行scrcpy命令,在较短的时间内就 ...
最新文章
- 客快物流大数据项目(五十三):实时ETL模块开发准备
- stylecloud.gen_stylecloud() 参数详解
- 新生代农民工必看:模拟器eNSP安装教程(附下载链接)
- [HNOI2016] 大数(莫队)
- android model 设计,Android model层设计
- 阿里P8架构师谈:分布式系统全局唯一ID简介、特点、5种生成方式
- python可以处理的文件类型_Python学习笔记之数据类型与文件处理
- 图解TCPIP-IP 网际协议-IP包
- Vue 中是如何解析 template 字符串为 VNode 的?
- py樱花代码_武汉大学生用代码敲出樱花绽放,这个开源项目也很酷炫
- jersey restful 测试_Jersey 开发RESTful(七)Jersey快速入门
- layui.table(表格)跨页多选
- 分布式IO模块ET 200SP基座单元( BaseUnit)使用方法
- mac 安装 Adobe CC XD
- html表单验证方法,简述HTML交互式表单验证方法
- html5显示状态灯,如何使用css3+html5来制作文字霓虹灯效果
- ChatGPT4 的体验 一站式 AI工具箱 -—Poe(使用教程)
- 集体备课模板_集体备课模板
- Mac 关闭双空格插入句号、自动大写首字母、拼写纠正
- 模块:time(时间)