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

写在前面

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

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

依赖关系.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')
}

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


项目目录结构

其中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<? extends TypeElement> 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的全类名
    如下图:
    image.png
  • @SupportedAnnotationTypes 能处理的注解类型,里面接受的是一个注解,说明可以同时处理多个,butterknife就是支持多个,同时处理BindView和OnClick注解,如果不使用注解的话,你也可以重写getSupportedAnnotationTypes方法,getSupportedAnnotationTypes返回的是一个set<String>集合,里面添加需要处理的集合信息
    如:
   @Override
   public Set<String> getSupportedAnnotationTypes() {
       Set<String> 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,点击打开

2CF280D9-C7A5-4098-BB83-C960E3BDE192.png

2.点击+号添加Remote

9A0EBE91-6713-4858-A371-D5C2D76D719C.png

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

B3101456-9C90-4378-A6E0-B223D206DC12.png

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

1BDD0EC9-A6A4-4344-B501-BC88A7BDF4AA.png

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

image.png

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

image.png

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

image.png

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

image.png

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容