Timber获取当前Class的Name做tag的源码分析

首先getTag是声明在 Tree这个类里面的,
Tree类是初始化要new的对象,不然Timber是不会打印log的
默认的getTag()是通过ThreadLocal查找是否有通过Timber.tag("")函数设置的TAG如果有就是用,并清除,保证只用一次

public static abstract class Tree {
    final ThreadLocal<String> explicitTag = new ThreadLocal<>();

    @Nullable
    String getTag() {
      String tag = explicitTag.get();
      if (tag != null) {
        explicitTag.remove();
      }
      return tag;
    }
  }

那么获取class的name的方法是在哪里实现的呢?

  public static class DebugTree extends Tree {
    private static final int MAX_LOG_LENGTH = 4000;
    private static final int MAX_TAG_LENGTH = 23;
    private static final int CALL_STACK_INDEX = 5;
    private static final Pattern ANONYMOUS_CLASS = Pattern.compile("(\\$\\d+)+$");
 /**
     * Extract the tag which should be used for the message from the {@code element}. By default
     * this will use the class name without any anonymous class suffixes (e.g., {@code Foo$1}
     * becomes {@code Foo}).
     * <p>
     * Note: This will not be called if a {@linkplain #tag(String) manual tag} was specified.
     */
    @Nullable
    protected String createStackElementTag(@NotNull StackTraceElement element) {
      String tag = element.getClassName();
      Matcher m = ANONYMOUS_CLASS.matcher(tag);
      if (m.find()) {
        tag = m.replaceAll("");
      }
      tag = tag.substring(tag.lastIndexOf('.') + 1);
      // Tag length limit was removed in API 24.
      if (tag.length() <= MAX_TAG_LENGTH || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return tag;
      }
      return tag.substring(0, MAX_TAG_LENGTH);
    }

    @Override final String getTag() {
      String tag = super.getTag();
      if (tag != null) {
        return tag;
      }

      // DO NOT switch this to Thread.getCurrentThread().getStackTrace(). The test will pass
      // because Robolectric runs them on the JVM but on Android the elements are different.
      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]);
    }
    ...
    }

就是这里,DebugTree,首先super.getTag()如果有用户设置的tag还是用用户设置的,如果没有就通过getStackTrace去获取栈信息找到现在的类名,并且不能使用Thread.getCurrentThread().getStackTrace()可能会不准。
注意:这个方法是有性能消耗的,所以最好只在Debug的时候用,线上包不要用!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值