ButterKnife省略findViewById的原理
Posted zhangjin1120
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ButterKnife省略findViewById的原理相关的知识,希望对你有一定的参考价值。
- ButterKnife是JakeWhartorn及其他程序员开发的第三方库。
- ButterKnife源码地址:ButterKnife.java
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
以上是关于ButterKnife省略findViewById的原理的主要内容,如果未能解决你的问题,请参考以下文章
厌烦了写findViewById 试试ButterKnife吧
告别findViewById(),ButterKnife,使用Google Data Binding Library
你还在苦逼地findViewById吗?使用ButterKnife从此轻松定义控件
Android Studio插件之快速findViewById(butterknife和Android CodeGenerator的使用)