写点什么

Android 基础系列(3)编译时注解处理器 APT,android 订餐系统源码

用户头像
Android架构
关注
发布于: 刚刚
  1. 定义注解

  2. 定义注解处理器(AbstractProcess)

  3. 处理器中生成 java 代码(可以采用 javaPoet)

  4. 注册处理器(AutoService)



创建 apt-annotation 模块

定义BindView注解


@Retention(RetentionPolicy.CLASS) // 编译时注解 @Target(ElementType.FIELD) // 注解范围为类成员 public @interface BindView {int value();}


创建 apt-processor 模块

定义注解处理器,生成需要的代码,注册处理器


// BindViewProcessor.java@AutoService(Processor.class) // 注册处理器 public class BindViewProcessor extends AbstractProcessor {


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


// ProcessingEnvironment 提供很多有用的工具类 Elements, Types 和 Filer@Overridepublic synchronized void init(ProcessingEnvironment processingEnv) {super.init(processingEnv);mElementUtils = processingEnv.getElementUtils();}


/**


  • 指定这个注解处理器是注册给哪个注解的,这里是 BindView*/@Overridepublic Set<String> getSupportedAnnotationTypes() {HashSet<String> supportTypes = new LinkedHashSet<>();supportTypes.add(BindView.class.getCanonicalName());return supportTypes;}


/**


  • 指定使用的 Java 版本,通常这里返回 SourceVersion.latestSupported()*/@Overridepublic SourceVersion getSupportedSourceVersion() {return SourceVersion.latestSupported();}


@Overridepublic boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {//根据注解生成 Java 文件 mProxyMap.clear();//得到所有的注解 Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(BindView.class);for (Element element : elements) {VariableElement variableElement = (VariableElement) element;TypeElement classElement = (TypeElement) variableElement.getEnclosingElement();String fullClassName = classElement.getQualifiedName().toString();ClassCreatorProxy proxy = mProxyMap.get(fullClassName);if (proxy == null) {proxy = new ClassCreatorProxy(mElementUtils, classElement);mProxyMap.put(fullClassName, proxy);}BindView bindAnnotation = variableElement.getAnnotation(BindView.class);int id = bindAnnotation.value();proxy.putElement(id, variableElement);}for (String key : mProxyMap.keySet()) {ClassCreatorProxy proxyInfo = mProxyMap.get(key);JavaFile javaFile = JavaFile.buil


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


der(proxyInfo.getPackageName(), proxyInfo.generateJavaCode()).build();try {// 生成文件 javaFile.writeTo(processingEnv.getFiler());} catch (IOException e) {e.printStackTrace();}}


return true;}}


// ClassCreatorProxy.java// JavaPoet 生成 java 代码 public class ClassCreatorProxy {private String mBindingClassName;private String mPackageName;private TypeElement mTypeElement;private Map<Integer, VariableElement> mVariableElementMap = new HashMap<>();


public ClassCreatorProxy(Elements elementUtils, TypeElement classElement) {this.mTypeElement = classElement;PackageElement packageElement = elementUtils.getPackageOf(mTypeElement);String packageName = packageElement.getQualifiedName().toString();String className = mTypeElement.getSimpleName().toString();this.mPackageName = packageName;this.mBindingClassName = className + "_ViewBinding";}


public void putElement(int id, VariableElement element) {mVariableElementMap.put(id, element);}


/**


  • 创建 Java 代码*/public TypeSpec generateJavaCode() {return TypeSpec.classBuilder(mBindingClassName).addModifiers(Modifier.PUBLIC).addMethod(generateMethods()).build();


}

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android基础系列(3)编译时注解处理器APT,android订餐系统源码