使用annotationProcessor打造编译时的注解(一)

写在前面

目前越来越多的框架使用编译时的注解,比如butterknife,Dagger2,EventBus等,下面以Butterknife为例一步一步的实现编译时的注解,算是高仿butterknife吧,如果想学习编译时的注解的话,不妨看下去,也许能帮助到你,如果你已经了解了的话就没必要看下去了。本系列将会由浅入深,可以说是从入门到精通吧,当你了解了的话,你会发现其实编译时的注解也没什么,只是不太熟悉其api而已,接下来介绍如何搭建项目,介绍api的使用,然后打造一个butterknife。准备拆分3篇来讲,这一篇主要是项目的搭建以及如何来debug

项目moudle之间的依赖关系如下图

使用annotationProcessor打造编译时的注解(一)_第1张图片
依赖关系.png

注:其中butterKnife-compiler、butterKnife-annoation为java lib

  • butterKnife-annoation:专门存放注解的module
  • butterKnife-compiler : 专门处理注解的module
  • butterKnife-core: 使用编译生成的代码并提供api供上层使用

创建butterKnife-annoation

其build.gradle

apply plugin: 'java-library'

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

sourceCompatibility = "1.7"
targetCompatibility = "1.7"

创建butterKnife-compiler

其build.gradle

apply plugin: 'java-library'

dependencies {
   implementation fileTree(include: ['*.jar'], dir: 'libs')
   implementation project(':butterKnife-annoation')
   implementation 'com.google.auto.service:auto-service:1.0-rc2'
   implementation 'com.squareup:javapoet:1.8.0'
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"

创建butterKnife-core

其build.gradle中的依赖

dependencies {
    ...
    api project(':butterKnife-annoation')
}

app module中依赖

dependencies {
    ...
    implementation project(':butterknife-core')
    annotationProcessor project(':butterKnife-compiler')
}

项目创建完了之后的目录结构为


使用annotationProcessor打造编译时的注解(一)_第2张图片
项目目录结构

其中2个注解如下,不懂注解的同学,请自行百度,这里就不作介绍了,这里butterknife-core中的类这里可以忽视,后面需要用到时再讲

/**
* Created by cool on 2018/7/3.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface OnClick {
   int[] value();
}

/**
* Created by cool on 2018/7/1.
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface BindView {
   int value();
}

下面来到了我们的重点BindViewProcessor,将详细介绍这个类

BindViewProcessor.java

@AutoService(Processor.class)//自动注册
@SupportedAnnotationTypes("com.cool.butterknife.annoation.BindView")//指名要处理的注解
@SupportedSourceVersion(SourceVersion.RELEASE_7)//知名支持的java版本
public class BindViewProcessor extends AbstractProcessor {

   private Messager messager;//打印日志的类
   private Filer filer;
   private Elements elementUtils;//元素节点工具

   @Override
   public synchronized void init(ProcessingEnvironment processingEnvironment) {
       super.init(processingEnvironment);
       filer = processingEnvironment.getFiler();
       messager = processingEnvironment.getMessager();
       elementUtils = processingEnvironment.getElementUtils();
       messager.printMessage(Diagnostic.Kind.NOTE, "=====init=====");
   }

   @Override
   public boolean process(Set set, RoundEnvironment roundEnvironment) {
       messager.printMessage(Diagnostic.Kind.NOTE, "=====process=====");
       return false;
   }
}

解释一下上面涉及到的注解:

  • @AutoService 这个注解能帮助我们自动注册,对应com.google.auto.service:auto-service:1.0-rc2如果不使用这个注解的话,需要手动去注册,步骤是,在butterKnife-compilermodule的main目录下创建resources/META-INF/services文件夹,再创建javax.annotation.processing.Processor文件,文件中写BindViewProcessor的全类名
    如下图:
    使用annotationProcessor打造编译时的注解(一)_第3张图片
    image.png
  • @SupportedAnnotationTypes 能处理的注解类型,里面接受的是一个注解,说明可以同时处理多个,butterknife就是支持多个,同时处理BindView和OnClick注解,如果不使用注解的话,你也可以重写getSupportedAnnotationTypes方法,getSupportedAnnotationTypes返回的是一个set集合,里面添加需要处理的集合信息
    如:
   @Override
   public Set getSupportedAnnotationTypes() {
       Set set = new HashSet<>();
       set.add("com.cool.butterknife.annoation.BindView");
       return set;
   }
  • @SupportedSourceVersion 支持的jdk版本,一般返回支持的最新的
 @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

重写方法或着使用注解达到的效果是一致的,怎样使用看个人习惯了

设置断点调试

logcat在这里就不再适用了,想打日志的话就只能用里面的Messager类了,需要在gradle控制台上查看输出的日志,但是只有日志的话还是远远不够的,这时我们需要像调试java程序一样能设置断点,这样能只管的看到程序运行时的状态,方便找错误,下面是设置断点调试的步骤

1. 在工具栏run中找到Edit Configurations,点击打开

使用annotationProcessor打造编译时的注解(一)_第4张图片
2CF280D9-C7A5-4098-BB83-C960E3BDE192.png

2.点击+号添加Remote

使用annotationProcessor打造编译时的注解(一)_第5张图片
9A0EBE91-6713-4858-A371-D5C2D76D719C.png

3.复制红框中的参数点击ok

使用annotationProcessor打造编译时的注解(一)_第6张图片
B3101456-9C90-4378-A6E0-B223D206DC12.png

4.打开gradle,找到红框中的条目点击打开

使用annotationProcessor打造编译时的注解(一)_第7张图片
1BDD0EC9-A6A4-4344-B501-BC88A7BDF4AA.png

5.将前面复制的参数粘贴到VM options,并将suspend=n改成suspend=y,再点击确定

使用annotationProcessor打造编译时的注解(一)_第8张图片
image.png

6.选上之前创建的Remote,再debug运行,这时发现debug的红点亮了,而且代码也没有执行编译,这是按第7步操作(debug运行前先在代码中设置好断点,并且clean一下项目)

image.png

7.打开gradle找到红框中的双击

使用annotationProcessor打造编译时的注解(一)_第9张图片
image.png

8.成功debug,如果不能成功debug,尝试先clean项目,如果还不行的话改一下端口,将5005改成别的端口,可能5005端口被别的占用了,或者点击debug右边的正方形红点,让其停止运行

使用annotationProcessor打造编译时的注解(一)_第10张图片
image.png

使用annotationProcessor打造编译时的注解(二)
使用annotationProcessor打造编译时的注解(三)

你可能感兴趣的:(使用annotationProcessor打造编译时的注解(一))