Android APT 注解开发--实践之BindView

什么是apt

APT(Annotation Processing Tool)即注解处理器,是一种处理注解的工具,确切的说它是javac的一个工具,它用来在编译时扫描和处理注解。注解处理器以Java代码(或者编译过的字节码)作为输入,生成.java文件作为输出。
简单来说就是在编译期,通过注解生成.java文件。

如果没接触过注解开发的同学可以看我之前的文章
Android注解--初探

apt 的作用

使用APT的优点就是方便、简单,可以少些很多重复的代码。

用过ButterKnife、Dagger、EventBus等注解框架的同学就能感受到,利用这些框架可以少些很多代码,只要写一些注解就可以了。
其实,他们不过是通过注解,生成了一些代码。

本文需求

通过APT实现一个功能,通过对View变量的注解,实现View的绑定(类似于ButterKnife中的@BindView)

创建项目

  • 创建Android Module命名为app 依赖 apt_library
  • 创建Java library Module命名为 apt_annotation
  • 创建Java library Module命名为 apt_processor 依赖 apt_annotation
  • 创建Android library Module 命名为 apt_library 依赖 apt_processor

注解开发需要创建Java library因为有些方法、类 Android library 中并不支持

Module职责

  • apt_annotation:自定义注解,存放@BindView
  • apt_processor:注解处理器,根据apt-annotation中的注解,在编译期生成xxxActivity_ViewBinding.java代码
  • apt_library:工具类,调用xxxActivity_ViewBinding.java中的方法,实现View的绑定。

实现

其实有两种方式可以实现这个功能

  1. RetentionPolicy.CLASS 编译时注解
  2. RetentionPoicy.RUNTIME 运行时注解

在很多情况下,运行时注解和编译时注解可以实现相同的功能,比如依赖注入框架,我们既可以在运行时通过反射来初始化控件,也可以再编译时就生成控件初始化代码。那么,这两者有什么区别呢?
答:编译时注解性能比运行时注解好,运行时注解需要使用到反射技术,对程序的性能有一定影响,而编译时注解直接生成了源代码,运行过程中直接执行代码,没有反射这个过程。

实现一:RetentionPolicy.CLASS 编译时注解

1、创建注解类BindView

/**
 * @author liuboyu  E-mail:545777678@qq.com
 * @Date 2019-08-21
 * @Description BindView 注解定义
 */
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface BindView {
    int value();
}

@Retention(RetentionPolicy.CLASS):表示编译时注解
@Target(ElementType.FIELD):表示注解范围为类成员(构造方法、方法、成员变量)

2、apt_processor(注解处理器)

在Module中添加依赖

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    api project(':apt_annotation')
}

创建BindViewProcessor

/**
 * @author liuboyu  E-mail:545777678@qq.com
 * @Date 2019-08-21
 * @Description 注解处理器
 */
public class BindViewProcessor extends AbstractProcessor {

    private Messager mMessager;
    private Elements mElementUtils;
    private Map<String, ClassCreatorProxy> mProxyMap = new HashMap<>();

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        mMessager = processingEnv.getMessager();
        mElementUtils = processingEnv.getElementUtils();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        HashSet<String> supportTypes = new LinkedHashSet<>();
        supportTypes.add(BindView.class.getCanonicalName());
        return supportTypes;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.RELEASE_8;
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        mMessager.printMessage(Diagnostic.Kind.NOTE, "processing...");
        mProxyMap.clear();
        //获得被BindView注解标记的element
        Set<? extends Element>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值