|
|
@@ -0,0 +1,347 @@
|
|
|
+package com.benyanyi.loglib
|
|
|
+
|
|
|
+import android.text.TextUtils
|
|
|
+import java.io.File
|
|
|
+import java.io.PrintWriter
|
|
|
+import java.io.StringWriter
|
|
|
+import java.lang.StringBuilder
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author myLove
|
|
|
+ * @time 2017/10/31 10:39
|
|
|
+ * @e-mail ben@yanyi.red
|
|
|
+ * @overview
|
|
|
+ */
|
|
|
+object Jlog {
|
|
|
+ @JvmField
|
|
|
+ internal val LINE_SEPARATOR = System.getProperty("line.separator")
|
|
|
+ private const val DEFAULT_MESSAGE = "********"
|
|
|
+ private const val PARAM = "Param"
|
|
|
+ private const val NULL = "null"
|
|
|
+ internal const val JSON_INDENT = 4
|
|
|
+
|
|
|
+ @JvmField
|
|
|
+ internal var mIsGlobalTagEmpty = true
|
|
|
+
|
|
|
+ @JvmField
|
|
|
+ internal var IS_INIT = true
|
|
|
+
|
|
|
+ @JvmField
|
|
|
+ internal var mConfig = LogConfig()
|
|
|
+
|
|
|
+ fun init(): LogConfig {
|
|
|
+ return mConfig
|
|
|
+ }
|
|
|
+
|
|
|
+ fun init(config: LogConfig) {
|
|
|
+ mConfig = config
|
|
|
+ }
|
|
|
+
|
|
|
+ fun v() {
|
|
|
+ printLog(LogType.V, null, DEFAULT_MESSAGE)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun v(msg: Any?) {
|
|
|
+ printLog(LogType.V, null, msg!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun v(length: Int, msg: Any?) {
|
|
|
+ printLog(LogType.V, null, msg!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun v(tag: Any?, vararg objects: Any) {
|
|
|
+ printLog(LogType.V, tag, *objects)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun d() {
|
|
|
+ printLog(LogType.D, null, DEFAULT_MESSAGE)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun d(msg: Any?) {
|
|
|
+ printLog(LogType.D, null, msg!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun d(tag: Any?, vararg objects: Any?) {
|
|
|
+ printLog(LogType.D, tag, *objects)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun i() {
|
|
|
+ printLog(LogType.I, null, DEFAULT_MESSAGE)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun i(msg: Any?) {
|
|
|
+ printLog(LogType.I, null, msg!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun i(tag: Any?, vararg objects: Any?) {
|
|
|
+ printLog(LogType.I, tag, *objects)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun w() {
|
|
|
+ printLog(LogType.W, null, DEFAULT_MESSAGE)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun w(msg: Any?) {
|
|
|
+ printLog(LogType.W, null, msg!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun w(tag: Any?, vararg objects: Any?) {
|
|
|
+ printLog(LogType.W, tag, *objects)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun e() {
|
|
|
+ printLog(LogType.E, null, DEFAULT_MESSAGE)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun e(msg: Any?) {
|
|
|
+ printLog(LogType.E, null, msg!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun e(tag: Any?, vararg objects: Any?) {
|
|
|
+ printLog(LogType.E, tag, *objects)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun a() {
|
|
|
+ printLog(LogType.A, null, DEFAULT_MESSAGE)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun a(msg: Any?) {
|
|
|
+ printLog(LogType.A, null, msg!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun a(tag: Any?, vararg objects: Any?) {
|
|
|
+ printLog(LogType.A, tag, *objects)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun json(jsonFormat: Any?) {
|
|
|
+ printLog(LogType.JSON, null, jsonFormat!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun json(tag: Any?, jsonFormat: String?) {
|
|
|
+ printLog(LogType.JSON, tag, jsonFormat!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun xml(xml: Any?) {
|
|
|
+ printLog(LogType.XML, null, xml!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun xml(tag: Any?, xml: String?) {
|
|
|
+ printLog(LogType.XML, tag, xml!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun file(targetDirectory: File, msg: Any) {
|
|
|
+ printFile(null, targetDirectory, null, msg)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun file(tag: Any?, targetDirectory: File, msg: Any) {
|
|
|
+ printFile(tag, targetDirectory, null, msg)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun file(tag: Any?, targetDirectory: File, fileName: String?, msg: Any) {
|
|
|
+ printFile(tag, targetDirectory, fileName, msg)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun debug() {
|
|
|
+ printDebug(null, DEFAULT_MESSAGE)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun debug(msg: Any?) {
|
|
|
+ printDebug(null, msg!!)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun debug(tag: Any?, vararg objects: Any?) {
|
|
|
+ printDebug(tag, *objects)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun trace() {
|
|
|
+ printStackTrace()
|
|
|
+ }
|
|
|
+
|
|
|
+ fun errorWriteFile(throwable: Throwable) {
|
|
|
+ if (mConfig.isWrite) {
|
|
|
+ BaseLog.writeError(mConfig.tag ?: "", throwable)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fun errorWriteFile(tag: String, throwable: Throwable) {
|
|
|
+ if (mConfig.isWrite) {
|
|
|
+ BaseLog.writeError(tag, throwable)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun printStackTrace() {
|
|
|
+ if (!IS_INIT && !mConfig.isWrite) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!mConfig.isShowLog && isApkInDebug && !mConfig.isWrite) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ val tr = Throwable()
|
|
|
+ val sw = StringWriter()
|
|
|
+ val pw = PrintWriter(sw)
|
|
|
+ tr.printStackTrace(pw)
|
|
|
+ pw.flush()
|
|
|
+ val message = sw.toString()
|
|
|
+ val traceString = message.split("\\n\\t".toRegex()).toTypedArray()
|
|
|
+ val sb = StringBuilder()
|
|
|
+ sb.append("\n")
|
|
|
+ for (trace in traceString) {
|
|
|
+ if (trace.contains("at Jlog")) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ sb.append(trace).append("\n")
|
|
|
+ }
|
|
|
+ val contents = wrapperContent("null", sb.toString()) ?: return
|
|
|
+ val tag = contents[0]
|
|
|
+ val msg = contents[1]
|
|
|
+ val headString = contents[2]
|
|
|
+ BaseLog.printDefault(LogType.D, tag, headString + msg)
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun printLog(type: LogType, tagStr: Any?, vararg objects: Any?) {
|
|
|
+ if (!IS_INIT && !mConfig.isWrite) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!mConfig.isShowLog && isApkInDebug && !mConfig.isWrite) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ val contents = wrapperContent(tagStr, *objects) ?: return
|
|
|
+ val tag = contents[0]
|
|
|
+ val msg = contents[1]
|
|
|
+ val headString = contents[2]
|
|
|
+ when (type) {
|
|
|
+ LogType.V, LogType.D, LogType.I, LogType.W, LogType.E, LogType.A -> BaseLog.printDefault(
|
|
|
+ type,
|
|
|
+ tag,
|
|
|
+ headString + msg
|
|
|
+ )
|
|
|
+ LogType.JSON -> JsonLog.printJson(tag, msg, headString)
|
|
|
+ LogType.XML -> XmlLog.printXml(tag, msg, headString)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun printDebug(tagStr: Any?, vararg objects: Any?) {
|
|
|
+ if (!IS_INIT || !mConfig.isWrite) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ val contents = wrapperContent(tagStr, *objects) ?: return
|
|
|
+ val tag = contents[0]
|
|
|
+ val msg = contents[1]
|
|
|
+ val headString = contents[2]
|
|
|
+ BaseLog.printDefault(LogType.D, tag, headString + msg)
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun printFile(tagStr: Any?, targetDirectory: File, fileName: String?, objectMsg: Any) {
|
|
|
+ if (!IS_INIT && !mConfig.isWrite) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!mConfig.isShowLog && isApkInDebug && !mConfig.isWrite) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ val contents = wrapperContent(tagStr, objectMsg) ?: return
|
|
|
+ val tag = contents[0]
|
|
|
+ val msg = contents[1]
|
|
|
+ val headString = contents[2]
|
|
|
+ FileLog.printFile(tag, targetDirectory, fileName, headString, msg)
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun wrapperContent(tagStr: Any?, vararg objects: Any?): Array<String>? {
|
|
|
+ val stackTrace = Thread.currentThread().stackTrace
|
|
|
+ var fileName = ""
|
|
|
+ var targetElement: StackTraceElement? = null
|
|
|
+ for (element in stackTrace) {
|
|
|
+ val name = element.fileName
|
|
|
+ val packageName = element.javaClass.getPackage()!!.name
|
|
|
+ if ("VMStack.java" != name && "Thread.java" != name && "Jlog.kt" != name
|
|
|
+ && "KtUtils.kt" != name
|
|
|
+ ) {
|
|
|
+ fileName = name
|
|
|
+ targetElement = element
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (targetElement == null) {
|
|
|
+ return null
|
|
|
+ }
|
|
|
+ val str = "$"
|
|
|
+ if (fileName.contains(str)) {
|
|
|
+ fileName = fileName.split("\\$".toRegex()).toTypedArray()[0]
|
|
|
+ }
|
|
|
+ val methodName = targetElement.methodName
|
|
|
+ var lineNumber = targetElement.lineNumber
|
|
|
+ if (lineNumber < 0) {
|
|
|
+ lineNumber = 0
|
|
|
+ }
|
|
|
+ var tag = (tagStr ?: fileName).toString()
|
|
|
+ if (mIsGlobalTagEmpty && TextUtils.isEmpty(tag)) {
|
|
|
+ tag = mConfig.tagDefault
|
|
|
+ } else if (!mIsGlobalTagEmpty) {
|
|
|
+ tag = mConfig.tagDefault
|
|
|
+ }
|
|
|
+ val msg = getObjectsString(*objects)
|
|
|
+ val headString = "[ ($fileName:$lineNumber)#$methodName ] "
|
|
|
+ return arrayOf(tag, msg, headString)
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun getObjectsString(vararg objects: Any?): String {
|
|
|
+ return if (objects.size > 1) {
|
|
|
+ val stringBuilder = StringBuilder()
|
|
|
+ stringBuilder.append("\n")
|
|
|
+ for (i in objects.indices) {
|
|
|
+ val `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`).append("\n")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ stringBuilder.toString()
|
|
|
+ } else {
|
|
|
+ val `object` = objects[0]
|
|
|
+ `object`?.toString() ?: NULL
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // try {
|
|
|
+// @SuppressLint("PrivateApi")
|
|
|
+// Class<?> activityThread = Class.forName("android.app.ActivityThread");
|
|
|
+// Object thread = activityThread.getMethod("currentActivityThread").invoke(null);
|
|
|
+// Object app = activityThread.getMethod("getApplication").invoke(thread);
|
|
|
+// Application application;
|
|
|
+// if (app == null) {
|
|
|
+// application = null;
|
|
|
+// } else {
|
|
|
+// application = (Application) app;
|
|
|
+// }
|
|
|
+// ApplicationInfo info = application.getApplicationInfo();
|
|
|
+// return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0;
|
|
|
+// } catch (Exception e) {
|
|
|
+// return false;
|
|
|
+// }
|
|
|
+ private val isApkInDebug: Boolean
|
|
|
+ get() = BuildConfig.DEBUG
|
|
|
+ // try {
|
|
|
+// @SuppressLint("PrivateApi")
|
|
|
+// Class<?> activityThread = Class.forName("android.app.ActivityThread");
|
|
|
+// Object thread = activityThread.getMethod("currentActivityThread").invoke(null);
|
|
|
+// Object app = activityThread.getMethod("getApplication").invoke(thread);
|
|
|
+// Application application;
|
|
|
+// if (app == null) {
|
|
|
+// application = null;
|
|
|
+// } else {
|
|
|
+// application = (Application) app;
|
|
|
+// }
|
|
|
+// ApplicationInfo info = application.getApplicationInfo();
|
|
|
+// return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0;
|
|
|
+// } catch (Exception e) {
|
|
|
+// return false;
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+ fun aaa(vararg str: String) {}
|
|
|
+
|
|
|
+}
|