转载地址:http://brucezz.itscoder.com/articles/2016/08/06/use-apt-in-android/?sukey=3997c0719f151520da61f552e1b96edf6ace9fb3d390e2f6955da10897d9d8c7522ada13476a493145eccaee38a1f4d6
APT(Annotation Processing Tool
的简称),可以在代码编译期解析注解,并且生成新的 Java 文件,减少手动的代码输入。现在有很多主流库都用上了 APT,比如 Dagger2, ButterKnife, EventBus3 等,我们要紧跟潮流,与时俱进呐! (ง •̀_•́)ง
下面通过一个简单的 View 注入项目 ViewFinder
来介绍 APT 相关内容,简单实现了类似于ButterKnife
中的两种注解 @BindView
和 @OnClick
。
项目地址:https://github.com/brucezz/ViewFinder
大概项目结构如下:
viewFinder-annotation
- 注解相关模块viewFinder-compiler
- 注解处理器模块viewfinder
- API 相关模块sample
- 示例 Demo 模块
实现目标
在通常的 Android 项目中,会写大量的界面,那么就会经常重复地写一些代码,比如:
TextView text = (TextView) findViewById(R.id.tv);
text.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// on click
}
});
天天写这么冗长又无脑的代码,还能不能愉快地玩耍啦。所以,我打算通过 ViewFinder
这个项目替代这重复的工作,只需要简单地标注上注解即可。通过控件 id 进行注解,并且@OnClick
可以对多个控件注解同一个方法。就像下面这样子咯:
@BindView(R.id.tv) TextView mTextView;
@OnClick({R.id.tv, R.id.btn})
public void onSomethingClick() {
// on click
}
定义注解
创建 module
viewFinder-annotation
,类型为 Java Library,定义项目所需要的注解。
在 ViewFinder
中需要两个注解 @BindView
和 @OnClick
。实现如下:
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface BindView {
int value();
}
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface OnClick {
int[] value();
}
@BindView
需要对成员变量进行注解,并且接收一个 int 类型的参数; @OnClick
需要对方法进行注解,接收一组 int 类型参数,相当于给一组 View 指定点击响应事件。
编写 API
创建 module
viewfinder
,类型为 Android Library。在这个 module 中去定义 API,也就是去确定让别人如何来使用我们这个项目。
首先需要一个 API 主入口,提供静态方法直接调用,就比如这样:
ViewFinder.inject(this);
同时,需要为不同的目标(比如 Activity、Fragment 和 View 等)提供重载的注入方法,最终都调用 inject()
方法。其中有三个参数:
host
表示注解 View 变量所在的类,也就是注解类source
表示查找 View 的地方,Activity & View 自身就可以查找,Fragment 需要在自己的 itemView 中查找provider
是一个接口,定义了不同对象(比如 Activity、View 等)如何去查找目标 View,项目中分别为 Activity、View 实现了Provider
接口(具体实现参考项目代码吧