Android studio 4.0 关于编译时注解处理器踩的坑

最近在研究注解看了刘望舒大大的编译时注解处理器,按步骤操作,make project的时候突然掉坑里了,如下图

场景还原:

1.定义注解

这里首先在项目中new module->java or Kotlin Library来专门存放注解,这个Library名为annotations。接下来定义注 解,如下所示:

@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface BindView {

    int value() default 1;
}

2.编写注解处理器

接着在项目中new module->java or Kotlin Library来专门存放注解,这个Library名为processor。配置下processor库的build.gradle

apply plugin: 'java-library'

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

sourceCompatibility = "1.7"
targetCompatibility = "1.7"

接下来编写注解处理器ClassProcessor,它继承AbstractProcessor,如下所示:

package com.ljp.laucher.processor;

import com.ljp.laucher.annotations.BindView;

import java.util.LinkedHashSet;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;

public class ClassProcessor extends AbstractProcessor {
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        //被注解处理工具调用,并输入 ProcessingEnviroment 参数。
        // ProcessingEnviroment提供很多有用的 工具类,
        // 比如Elements、Types、Filer和Messager等。
        super.init(processingEnv);
    }

    @Override
    public boolean process(Set< ? extends TypeElement > annotations, RoundEnvironment roundEnv) {
        //相当于每个处理器的主函数main(),在这里写你的扫描、评估和处理注解的代码,
        // 以及生 成Java文件。输入参数RoundEnviroment,可以让你查询出包含特定注解的被注解元素。
        Messager messager = processingEnv.getMessager();
        for (Element element : roundEnv.getElementsAnnotatedWith(BindView.class)) {
            if (element.getKind() == ElementKind.FIELD) {
                messager.printMessage(Diagnostic.Kind.NOTE, "printMessage:" + element.toString());
            }
        }
        return false;
    }

    @Override
    public Set< String > getSupportedAnnotationTypes() {
        //这是必须指定的方法,指定这个注解处理器是注册给哪个注解的。
        // 注 意,它的返回值是一个字符串的集合,包含本处理器想要处理的注解类型的合法全称。
        Set< String > annotataions = new LinkedHashSet<>();
        annotataions.add(BindView.class.getCanonicalName());
        return annotataions;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        //用来指定你使用的 Java 版本,通常这里返回 SourceVersion.latestSupported()。
        return SourceVersion.latestSupported();
    }
}

3.注册注解处理器

为了能使用注解处理器,需要用一个服务文件来注册它。现在我们就来创建这个服务文件。首先在 processor 库的 main 目录下新建 resources 资源文件夹,接下来在 resources 中再建立 META-INF/services目录 文件夹。最后在 META-INF/services 中创建 javax.annotation.processing.Processor文件,这个文件中的内容是 注解处理器的名称。这里我们的javax.annotation.processing.Processor文件的内容为“ com.ljp.laucher.processor.ClassProcessor”
整体代码结构如下所示:
4.应用注解
接下来在我们的主工程项目( app )中引用注解。首先要在主工程项目的 build.graldle 中引用 annotations
processor 这两个库:
dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    //注意千万不要使用implementation,因为这个运行时注解要在运行时生效
    //用implementation会使processor和app的build下面生成的classes.dex中都定义了
    //com.ljp.laucher.processor.ClassProcessor导致冲突
    annotationProcessor project(":processor")
    implementation project(":annotations")
}
接下来在 MainActivity 中应用注解,如下所示:
package com.ljp.laucher.testannotation;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

import com.ljp.laucher.annotations.BindView;

public class MainActivity extends AppCompatActivity {

    @BindView(value = R.id.tv_test_bind_view)
    TextView tv_test_bind_view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

接下来快乐的时光来了,先clean project再make project(Android Studio 4.0的Gradle Console合并到build output中了),运行结果如下

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值