前言
Android的日志类使用方式一般为
Log.e(TAG,msg)
Tag值的命名一般都让人头疼,常见的做法是将Tag设为类名,但每次要打log都得给类设置一个TAG变量,写着很烦人。此篇的目的便是解决此问题,将TAG的命名抽取出来,我们只需要关心Log的msg即可。
直接上代码
/**
* @desc: 通用的日志类,包装了Tag 格式:[类名].[方法名]:[代码行]
*/
object LogUtil {
private const val BASE_CLASS_PATH = "com.example."
fun v(msg: String){
Log.v(getCallerInfo(),msg)
}
fun d(msg: String){
Log.d(getCallerInfo(),msg)
}
fun i(msg: String){
Log.i(getCallerInfo(),msg)
}
fun w(msg: String){
Log.w(getCallerInfo(),msg)
}
fun e(msg: String) {
Log.e(getCallerInfo(), msg)
}
private fun getCallerInfo(): String {
val stackTrace = Thread.currentThread().stackTrace
//0 VMStack.getThreadStackTrace
//1 Thread.getStackTrace
//2 LogUtil.getCallerInfo
//3 LogUtil.e
//4 Caller
val caller = stackTrace[4]
return "${simplifyClassName(caller.className)}.${caller.methodName}:${caller.lineNumber}"
}
private fun simplifyClassName(className: String): String{
return className.substringAfter(BASE_CLASS_PATH)
}
}
代码主要在于getCallerInfo方法,会拿到当前线程堆栈,获取到调用LogUtil的方法相关信息,这里我们使用了[类名],[方法名]和[代码行]的信息来组成Tag的内容。
至于要拿到stackTrace[4]这个栈元素是因为栈顶往下分别是
//0 VMStack.getThreadStackTrace
//1 Thread.getStackTrace
//2 LogUtil.getCallerInfo
//3 LogUtil.e
//4 Caller
Caller即为调用LogUtil的方法,这个通过调试,查看stackTrace的内容可以很容易发现。
另外我们可以指定项目的包名(即我们打Log的Class全名的公共前缀,BASE_CLASS_PATH),来简化TAG。