ButterKnife源码探究(附实现自定义注解处理器)

这样就只需要在MainActivity的onCreate方法中调用MainActivity_Inject的构造方法就能完成成员变量的初始化了。

所以接下来的任务就是解析在代码中使用的注解,根据注解生成MainActivity_Inject.java这个文件

(3)解析注解

新建一个Java Library模块命名为compiler,在其中创建一个类InjectProcessor,继承自AbstractProcessorAbstractProcessor类为注解处理器的抽象类。在编译阶段,会查找指定的注解处理器实现类,并调用其process方法,完成注解的解析。

//配置注解处理器支持处理的注解类型为InjectString和InjectInt

@SupportedAnnotationTypes({“com.example.annotations.InjectString”,

“com.example.annotations.InjectInt”})

//配置注解处理器支持的Java版本

@SupportedSourceVersion(SourceVersion.RELEASE_7)

@AutoService(Processor.class)

//定义注解处理器继承自AbstractProcessor

public class InjectProcessor extends AbstractProcessor{

private static final ClassName CONTEXT = ClassName.get(“android.content”, “Context”);

//待生成java文件的的集合,key为被注解的类的类名,value为GenerateJavaFile对象

private HashMap<String,GenerateJavaFile> mGenerateJavaFiles = new HashMap<String, GenerateJavaFile>();

/**

  • 实现process方法,完成注解的解析和处理,通常生成文件或者校验处理

  • @param set 定义的注解类型的集合

  • @param roundEnvironment 回合环境,注解的处理可能要经过几个回合的处理,每个回合处理一批注解

  • @return 返回true表示注解被当前注解处理器处理,就不会再交给其他注解处理器

*/

@Override

public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {

//遍历所有的TypeElement的,一个注解类型对应一个TypeElement

for (TypeElement typeElement : set) {

//遍历在代码中使用typeElement对应注解类型来注解的元素

//例如:如果typeElement对应的是InjectString注解类型,那么Element对应为使用@InjectString注解的成员变量

for (Element element : roundEnvironment.getElementsAnnotatedWith(typeElement)) {

//添加注解元素到将要生成的java文件对应的GenerateJavaFile的对象中

addElementToGenerateJavaFile(element);

}

}

//生成java文件

createJavaFile();

return true;

}

}

因为之前定义的InjectString和InjectInt是类,所以他们的Element类型是TypeElement,一个TypeElement对应一个注解类型,所以process传入的set集合中有两个TypeElement对象,分别对应InjectString和InjectInt,我们遍历set集合,处理每个注解类型。通过调用roundEnvironment的getElementsAnnotatedWith(typeElement)来获取一个注解类型注解了哪些元素。

比如我们使用了InjectStirng注解了两个字符串成员变量:

@InjectString

public String hello;

@InjectString

public String world;

在InjectStirng的TypeElement会遍历hello和world这两个Element 。因为我们要将注解的元素转化成Java代码,所以需要处理每个Element对象,为生成Java文件做准备。我们定义类GenerateJavaFile来描述一个待生成的Java文件在InjectProcessor中:

/**

  • 描述一个待生成的Java文件

*/

private static class GenerateJavaFile {

String packageName;//包名

String className;//类名

List elements;//注解元素集合

}

通过调用addElementToGenerateJavaFile方法创建GenerateJavaFile对象,并将Element对象加入到GenerateJa

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值