根据注解,创建代码的简单例子

根据注解,创建代码的简单例子

关于注解然后调用继承于AbstractProcessor类,可以做到编译时期插入新的代码。类似我们要求电脑在编译的时候顺便写下代码。(APT生成代码技术)感觉是AOP,面向切面编程。

AbstractProcessor类是帮助我们写代码的一个类。

首先写一个简单的例子

1、创建javaLib Module项目

创建一个Android 项目,在项目中创建一个javaLib Module 项目,起个名字叫AutoCode吧,自动代码的意思。

  1. 添加AutoCode需要的代码库
在AtuoCode 的build.gradle 中添加
dependencies{
...............
// 谷歌写的 用于编译的时候 会帮助生成代码 执行到
compile 'com.google.auto.service:auto-service:1.0-rc2'
//一个开源库,大佬封装的方法
compile 'com.squareup:javapoet:1.7.0'
}

以上AutoCode 的配置就完成了
2. 编写注解

现在写一个注解,就BindView 吧,我想自己写个注解来帮忙findViewById,写过反射的,但是效率低,想试试AOP。

@Target(ElementType.FIELD) //注解用于变量
@Retention(RetentionPolicy.CLASS)//编译的时候只会留下class文件
public @interface BindView {
int value();
}

写完注解,就可以写注解解释器了。注解只是一个标签,我们需要一个解释器在编译的时候发现有 这些标签的对象 来进行操作。

3.编写注解 解释器
创建一个继承AbstractProcessor的类,叫MyClass类吧。
这个类在编译的时候不会自动执行,但是刚刚上面导入了谷歌的库:

compile 'com.google.auto.service:auto-service:1.0-rc2'  

所以可以使用一个@AutoService注解,编译期间会自动执行到。
跟下面一样:

@AutoService(Processor.class)
public class MyClass extends AbstractProcessor {
.......
}

AbstractProcessor 类中,需要实现4个方法

init : 初始化操作
getSupportedAnnotationTypes :绑定注解类
getSupportedSourceVersion :确定使用的JDK版本
process :帮我们创建代码的操作都在这里完成

以下我贴代码:

@AutoService(Processor.class)
public class MyClass extends AbstractProcessor {
{
   /**
     * 文件相关的辅助类
     */
    private Filer mFiler;
    /**
     * 元素相关的辅助类
     */
    private Elements mElementUtils;
    /**
     * 日志相关的辅助类
     */
    private Messager mMessager;
     @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        mFiler = processingEnv.getFiler();
        mElementUtils = processingEnv.getElementUtils();
        mMessager = processingEnv.getMessager();
    }
    
     @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        TypeSpec myCodeClass = TypeSpec.classBuilder("MyCodeClass")
                .addModifiers(Modifier.PUBLIC)
                .build();
        JavaFile javaFile = JavaFile
                .builder("com.example.alex",
                        myCodeClass)
                .build();
        try {
            javaFile.writeTo(mFiler);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
    //绑定注解,对添加过绑定注解的变量进行操作
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> strings = new LinkedHashSet<>();
        strings.add(Override.class.getCanonicalName());
        strings.add(BindView.class.getCanonicalName());
        return strings;
    }

    //判定使用的jdk版本
    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.RELEASE_7;
    }
}

最后还要把javaLib Module添加到android 依赖中去

主模块APP下的build.gradle 文件添加配置
defaultConfig{
.....
//Process 可能会出异常,需要添加这条。
javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
}

dependencies{
......
//添加导入JavaLib包,因为有些类只有在java项目中才拥有
implementation project(':AutoCode')  
}

使用:直接在变量上使用注解就可以了

    @BindView(R.id.textView)
    private TextView mTextView;

效果图:
根据注解,创建代码的简单例子

总结:

1、创建JavaLib Module
添加配置、注解、注解解释器
2、主项目添加javaLib 依赖
3、使用注解