JakeWharton的timber自动生成Tag原理

JakeWharton的timber自动生成Tag原理

JakeWharton大神的timber是一个为懒人设计的、基于Android原生的Log扩展的Logger API。相对于原生的Log API,使用timber的好处是:

  • 无须指明TAG,自动以当前Class Name为TAG
  • 可以以String.format形式格式化输出日志内容

使用

从官网文档介绍,使用非常简单,分为2步:

  1. 在Application的oncreate进行初始化,如:
    Timber.plant(new Timber.DebugTree());
  2. 日志记录,如:
    Timber.d(“My Log”);

自动生成Tag原理

整个timber就一个Timber.java文件,也就500多行。通过阅读源码,我们可以发现生成Tag的代码:

@Override final String getTag() {
      String tag = super.getTag();
      if (tag != null) {
        return tag;
      }
      StackTraceElement[] stackTrace = new Throwable().getStackTrace();
      if (stackTrace.length <= CALL_STACK_INDEX) {
        throw new IllegalStateException(
            "Synthetic stacktrace didn't have enough elements: are you using proguard?");
      }
      return createStackElementTag(stackTrace[CALL_STACK_INDEX]);
    }

其中核心就是这两句话:

StackTraceElement[] stackTrace = new Throwable().getStackTrace();
return createStackElementTag(stackTrace[CALL_STACK_INDEX]);

而其中CALL_STACK_INDEX是定义的常量5。

为什么CALL_STACK_INDEX是5呢

我们还是从Timber.d()方法的调用堆栈入手,假设我们在DemoActivity里调用了Timber.d(“log”),调用时序如下:

Created with Raphaël 2.1.0 DemoActivity DemoActivity Timber Timber TREE_OF_SOULS TREE_OF_SOULS Tree Tree DebugTree DebugTree d("log") d("log") d("log") prepareLog("log") getTag()

从上面的时序图,我们可以知道new Throwable().getStackTrace()返回数组的前几个依次是:

  1. DebugTree
  2. Tree
  3. Tree
  4. TREE_OF_SOULS,也就是Timber$1
  5. Timber
  6. DemoActiviy

    因此,stackTrace[CALL_STACK_INDEX]也就是第6个DemoActivity就是我们所要获取的Tag

结论

timber自动生成Tag的技术要点就是:Throwable.getStackTrace()

这里的要强调一下Throwable.getStackTrace() 与

Thread.currentThread().getStackTrace()

是有所不同的,后者会多一些Thread.currentThread()的调用信息。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值