Android ButterKnife源码解析

本文深入探讨了ButterKnife的源码实现,解释了其使用APT注解处理器而非运行时注解以提高性能的原因。文章详细介绍了注解的类型,包括普通注解和元注解,以及自定义注解的实现。此外,还讲解了反射在ButterKnife中的应用及其可能带来的性能影响。ButterKnife的工作原理是编译时扫描注解并生成Java代码,运行时通过bind方法将ID与视图上下文绑定。文章深入到ButterKnifeProcessor、FieldViewBinding等相关类的源码中,揭示了其内部细节和关键方法的作用。
摘要由CSDN通过智能技术生成

1.ButterKnife是使用APT(AnnotationProcessor注解处理器,Javac的工具)进行注解,不是使用运行时注解,所以性能没有影响,但对编译器有点时间成本的影响
2.注解分为
普通注解 @Override等
元注解 注解其它注解的注解
1.@Document 应该被Java记录
2.@Target 注解的使用范围
3.@Retention 描述注解的生命周期
4.@inherited 表明注解可继承

3.自定义注解

@Documented
@Target(ElementType.TYPE)//ElementType.TYPE表示用来描述类或者接口(ElementType是枚举类)
@Retention(RetentionPolicy.RUNTIME)//RetentionPolicy.RUNTIME表明 运行时有效(RetentionPolicy是枚举类,也有英文注释)
@Inherited
public @interface metaTest {
    // @interface 表明自定义注解

   public String doTest();

}

看下ElementType

public enum ElementType {
     //有英文注释
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

看下@BindView源码

@BindView(R.id.tv_info)
TextView tv_info;
@Retention(RUNTIME)  //注释将由编译器记录在类文件中,并且在运行时由VM保留,因此可以反射地读取它们
@Target(FIELD) //字段声明(包括枚举常量)
public @interface BindView {
   
  /** View ID to which the field will be bound. */
  @IdRes int value();
}

注解处理器APT,每一个注解处理器都是继承于AbstractProcessor(注解处理器不能改变Java类)
看下AbstractProcessor这个类

package javax.annotation.processing;
public abstract class AbstractProcessor implements Processor {
   //四个核心方法(整个注解处理器是运行在自己的Java虚拟上的)
    protected ProcessingEnvironment processingEnv;
    private boolean initialized = false;

    protected AbstractProcessor() {
    //AbstractProcessor 构造函数是空的,它的初始化在init()方法中
    }
                               .
                               .
                               .
       public synchronized void init(ProcessingEnvironment var1) {
   
        if (this.initialized) {
   
            throw new IllegalStateException("Cannot call init more than once.");
        } else {
   
            Objects.requireNonNull(var1, "Tool provided null ProcessingEnvironment");
            this.processingEnv = var1;
            this.initialized = true;
        }
    }
       public abstract boolean process(Set<? extends TypeElement> var1, RoundEnvironment var2);//最重要的抽象方法,重要程度相当于Main函数,最后会生成Java代码
   .
       public Set<String> getSupportedAnnotationTypes() {
    //返回支持的注解的类型
        SupportedAnnotationTypes var1 = (SupportedAnnotationTypes)this.getClass().getAnnotation(SupportedAnnotationTypes.class);
        if (var1 == null) {
   
            if (this.isInitialized()) {
   
                this.processingEnv.getMessager().printMessage(Kind.WARNING, "No SupportedAnnotationTypes annotation found on " + this.getClass().getName() + ", returning an empty set.");
            }

            return Collections.emptySet();//通过集合来判断
        } else {
   
            return arrayToSet(var1.value());
        }
    } 
    public SourceVersion getSupportedSourceVersion() {
    //用来指定所支持的Java版本
        SupportedSourceVersion var1 = (SupportedSourceVersion)this.getClass().getAnnotation(SupportedSourceVersion.class);
        SourceVersion var2 = null;
        if (var1 == null) {
   
            var2 = SourceVersion.RELEASE_6;
            if (this.isInitialized()) {
   
                this.processingEnv.getMessager().printMessage(Kind.WARNING, "No SupportedSourceVersion annotation found on " + this.getClass().getName() + ", returning " + var2 + ".");
            }
        } else {
   
            var2 = var1.value();
        }

        return var2;
    }                   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值