1. 程式人生 > 其它 >kotlin 常用工具類LogUtil

kotlin 常用工具類LogUtil

技術標籤:Android

說明

列印日誌之前,通過 Thread.currentThread().stackTrace 方式獲取棧資訊,繼而獲取列印位置及列印行號。利用 studio 列印 (檔名:行號)格式會產生跳轉的超連結這個特性,實現點選日誌名跳轉的功能。

效果展示

MainActivity.kt 中呼叫如下:

LogUtil.i("MainActivity","test")

列印日誌如下(備註:這裡是示例效果,超連結不可用):

01-08 12:49:45.252 14800-14800/com.demo.logdemo I/MainActivity: (

MainActivity.kt:26)【onClickEvent】test

原始碼

  • LogUtil.kt
import android.util.Log
import java.lang.Exception
import java.lang.StringBuilder

/**
 * @author lenovo
 * @date 2021/1/8 12:21
 */

class LogUtil() {


    companion object {

        /**
         * 預設 TAG
         */
        val PUB_TAG = "Log"

        /**
         * 是否列印除錯日誌標誌位
         */
        val DEBUG_FLAG = true

        /**
         * 示例;
         * 通過這個方法找到你需要的那一層的索引值(index);然後配置到 getLogPre()方法中
         *stack.className:com.android.internal.os.ZygoteInit$MethodAndArgsCaller
         *stack.methodName:run
         *stack.fileName:ZygoteInit.java
         *stack.lineNumber:902
         */
        fun test() {
            Log.d(PUB_TAG, "--- start ---")
            getAllStackInfo()
            Log.d(PUB_TAG, "--- end ---")
        }

        fun getAllStackInfo() {
            val stackArray = Thread.currentThread().stackTrace
            if (stackArray.size > 0) {
                for ((index, stack) in stackArray.withIndex()) {
                    Log.d(PUB_TAG, "*****************")
                    Log.d(PUB_TAG, "index:" + index)
                    Log.d(PUB_TAG, "stack.className:" + stack.className)
                    Log.d(PUB_TAG, "stack.methodName:" + stack.methodName)
                    Log.d(PUB_TAG, "stack.fileName:" + stack.fileName)
                    Log.d(PUB_TAG, "stack.lineNumber:" + stack.lineNumber)
                    Log.d(PUB_TAG, "stack.isNativeMethod:" + stack.isNativeMethod)
                    Log.d(PUB_TAG, "==================")
                }
            }
        }

        fun v(msg: String) {
            if (getLogPre(PUB_TAG, msg, "v")) return
            Log.v(PUB_TAG, msg)
        }

        fun i(msg: String) {
            if (getLogPre(PUB_TAG, msg, "i")) return
            Log.i(PUB_TAG, msg)
        }

        fun d(msg: String) {
            if (!DEBUG_FLAG) {
                return
            }
            if (getLogPre(PUB_TAG, msg, "d")) return
            Log.d(PUB_TAG, msg)
        }


        fun e(msg: String) {
            if (getLogPre(PUB_TAG, msg, "e")) return
            Log.e(PUB_TAG, msg)
        }

        fun v(tag: String, msg: String) {
            if (getLogPre(tag, msg, "v")) return
            Log.v(tag, msg)
        }

        fun i(tag: String, msg: String) {
            if (getLogPre(tag, msg, "i")) return
            Log.i(tag, msg)
        }

        fun d(tag: String, msg: String) {
            if (!DEBUG_FLAG) {
                return
            }
            if (getLogPre(tag, msg, "d")) return
            Log.d(tag, msg)
        }


        fun e(tag: String, msg: String) {
            if (getLogPre(tag, msg, "e")) return
            Log.e(tag, msg)
        }

        /**
         * 組合特定格式的日誌字首,示例: (MainActivity.kt:26)【onClickEvent】
         */
        private fun getLogPre(tag: String, msg: String, grade: String): Boolean {
            try {
                val stackArray = Thread.currentThread().stackTrace
                //這個值是經過測試得出的;執行 test() 方法可以看出呼叫 LogUtil 的類 的 index = 4
                val index = 4
                if (stackArray.size > (index + 1)) {
                    val logTraceElement = stackArray[index]
                    val logPre = StringBuilder()
                    logPre.append("(")
                    logPre.append(logTraceElement.fileName)
                    logPre.append(":")
                    logPre.append(logTraceElement.lineNumber)
                    logPre.append(")")
                    logPre.append("【")
                    logPre.append(logTraceElement.methodName)
                    logPre.append("】")

                    when (grade) {
                        "v" -> {
                            Log.v(tag, logPre.toString() + msg)
                        }
                        "i" -> {
                            Log.i(tag, logPre.toString() + msg)
                        }
                        "d" -> {
                            Log.d(tag, logPre.toString() + msg)
                        }
                        "e" -> {
                            Log.e(tag, logPre.toString() + msg)
                        }
                    }

                    return true
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return false
        }
    }
}