我正在尝试创建一个日志类,如果构建是调试构建,则仅记录日志。这是我的类
import me.entri.entrime.BuildConfig
import me.entri.entrime.utils.Constants
object Logger {
private val TAG = Constants.LOGGING_TAG
@JvmStatic
fun d(message : Any?){
if (BuildConfig.DEBUG)
Log.d(TAG , message.toString())
}
@JvmStatic
fun d(message: Any? , e : Exception?){
if (BuildConfig.DEBUG)
Log.d(TAG , message.toString(), e)
}
@JvmStatic
fun e(message : Any?){
if (BuildConfig.DEBUG)
Log.e(TAG , message.toString())
}
@JvmStatic
fun e(message: Any? , e : Exception?){
if (BuildConfig.DEBUG)
Log.e(TAG , message.toString(), e)
}
@JvmStatic
fun w(message : Any?){
if (BuildConfig.DEBUG)
Log.w(TAG , message.toString())
}
@JvmStatic
fun w(message: Any? , e : Exception?){
if (BuildConfig.DEBUG)
Log.w(TAG , message.toString(), e)
}
@JvmStatic
fun v(message : Any?){
if (BuildConfig.DEBUG)
Log.v(TAG , message.toString())
}
@JvmStatic
fun v(message: Any? , e : Exception?){
if (BuildConfig.DEBUG)
Log.v(TAG , message.toString(), e)
}
}
正如您所看到的,目前我正在用字符串对TAG进行硬编码。但是我想将TAG设置为调用Log方法的类名。
例如:-这是splash.kt类,如果我调用
try{
val error = 4384/0 //arithmetic error for testing.
}catch(e : Exception){
Logger.e("message")
}
那么我的LogCat应该显示类名作为TAG。ie Splash.kt
我试着解剖Jake Wharton的木材库,它有这个功能。
他似乎做了这样的事情来从堆栈跟踪中获取类名。
@get:JvmSynthetic
internal val explicitTag = ThreadLocal<String>()
@get:JvmSynthetic
internal open val tag: String?
get() {
val tag = explicitTag.get()
if (tag != null) {
explicitTag.remove()
}
return tag
}
如果上面的标签是空的,那么像这样
override val tag: String?
get() = super.tag ?: Throwable().stackTrace
我不明白这两者是如何工作的,即使我试图使用相同的,我也无法获得调用Logger类的类名。相反,作为stacktrace类名,我得到的只是我的Logger类名本身。
所以我想知道是否有任何方法可以获得我的Logger类将被调用的类名。谢谢你
可以通过两种方式获得调用者类名。
1)使用StackWalker
val className = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).callerClass
使用StackWalker你需要Java 9
或Greater
2)使用线程StackTrace
这将获得当前线程的堆栈跟踪。
val className = Thread.currentThread().stackTrace[2].className
3)通过创建异常并获取其堆栈跟踪。
val className = Exception().stackTrace[1].className