ButterKnife省略findViewById的原理

Posted zhangjin1120

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ButterKnife省略findViewById的原理相关的知识,希望对你有一定的参考价值。

ButterKnife省略findViewById和setOnClickListener的大致原理是什么?

 插件自动补全Java注解BindView(R.id.tvName),和ButterKnife.bind(this);这行代码。
 项目在编译时,会读取所有java文件信息,并调用annotationProcessor,也就是ButterKnifeProcessor,来读取MainActivity的类信息,并通过javaPoet生成MainActivity_ViewBinding.java这个类文件。在这个类的构造方法中,包含了findViewById和setOnClickListener的逻辑。
  程序执行到onCreate()中的ButterKnife.bind(this)这行代码时,会反射生成一个MainActivity_ViewBinding类的对象vb,也就调用了它的构造方法,从而避免了开发者手写findViewById和setOnClickListener。

ButterKnifeProcessor具体什么时候被调用?

  在编译时,java编译器(javac)会去META-INF中查找实现了的AbstractProcessor的子类,并且调用该类的process函数,最终生成.java文件。其实就像activity需要注册一样,就是要到META-INF注册 ,javac才知道要给你调用哪个类来处理注解。参考:Android APT工作原理(annotationProcessor)

怎么自动生成MainActivity_ViewBinding.java的?

 JavaPoet这个库,可以自动生成.java代码。生成MainAcitivity_ViewBinding.java的逻辑在ButterKnifeProcessor中,详见JavaPoet - 优雅地生成代码

TextView对象是如何生成的?

ButterKnife.bind(this);这行代码传入了Activity对象,根据Activity实例可以获取DecorView,通过decorView.findViewById(id)获取TextView对象。

findViewById方法需要一个参数id,如何获取这个id?

 根据Activity实例,反射获取每一个属性Field,再反射获取Field的注解:BindView bindView = field.getAnnotation(BindView.class);,在从注解里面获取具体的id值:int id = bindView.value();。这个过程,这篇文章讲的通俗易懂:Butterknife之从反射到注解
 在源码中,获取id的逻辑在ButterKnifeProcessor的parseBindView()方法中:

    // Assemble information on the field.
    int id = element.getAnnotation(BindView.class).value();

 直接贴出源码位置:ButterKnifeProcessor:495

8.8.1版本源码分析:ButterKnife原理解析看这篇文章就够了

以上是关于ButterKnife省略findViewById的原理的主要内容,如果未能解决你的问题,请参考以下文章

厌烦了写findViewById 试试ButterKnife吧

告别findViewById(),ButterKnife,使用Google Data Binding Library

你还在苦逼地findViewById吗?使用ButterKnife从此轻松定义控件

Android Studio插件之快速findViewById(butterknife和Android CodeGenerator的使用)

ButterKnife -- 源码分析 -- 在‘编译期’间生成findViewById等代码

ButterKnife -- 源码分析 -- 在‘编译期’间生成findViewById等代码