一、ButterKnife的使用
Android Butterknife使用方法总结 - 简书
二、原理浅析
ButterKnife通过注解就能进行view、string、点击事件的绑定,那么它里面到底做了什么呢?ButterKnife.bind(this)是如何进行绑定的?
bind(this)DecorView是activity窗口的根视图,内部又分为两部分,一部分是ActionBar,另一部分是ContentParent,即activity在setContentView对应的布局。既然根布局都拿到了,那么我们就可以使用findViewById(id)来拿到组件了,问题是如何才能拿到id呢?ButterKnife要求使用注解的变量不能是private,因为这样butterKnife才能通过activity.变量名来拿到变量,才能绑定。
findBindingConstructorForClass(targetClass)拿到的是注解解析器生成的java类的构造函数,解析器生成的java命名规则是clsName_ViewBinding,这个clsName就是你的Activity或Fragment类名,生成的类同时会实现Unbinder接口用于解绑。实例化解析器生成的java类
bindingClass就是注解解析器生成的类,然后调用它的getConstructor(cls, View.class)拿到它的两个参数的构造方法返回。
到此我们并没有看到绑定的操作,只知道了bing()最终实例化了注解解析器生成的java类,由此推测,绑定的操作应该就在那个构造函数里实现的。
注解解析器生成的Java类会放在build->generated->source->apt下
生成的java文件这个target就是我们bind(this)传进来的activity,因为backBtn、tagName这些变量在activity中是public的所以能直接访问到,Utils.findRequiredViewAsType()就是根据id来获取布局中的组件。
可以看到它也是通过source.findViewById(id)来获取布局中的控件的,这个source就还根布局,说白了跟我们自己写view=findViewById(id)没啥区别。
还有一个问题就是注解解析器是如何根据注解来自动生成相应的java文件的呢?通过自定义注解处理器,继承AbstractProcessor,指定要处理的注解,实现process()方法,在process()中根据Activity中的注解信息以及借助一些生成源文件的库(如:JavaPoet)动态生成java文件,向编译器注册注解处理器
网友评论