android自定义注解

1. 创建AnnotationProject

2. 增加注解compile module

必须java Library

2.1 自定义注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {
    String name();
}

2.2 定义注解处理器

@AutoService(Processor.class)
public class MyAnnotationProcessor extends AbstractProcessor{
    Filer mFiler;
    Messager mMessager;
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        mMessager = processingEnv.getMessager();
        mFiler = processingEnv.getFiler();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> annoation = new LinkedHashSet<>();
        annoation.add(MyAnnotation.class.getCanonicalName());
        return annoation;
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) {
        if (set == null || set.isEmpty()) {
            info(">>elements is null<<");
            return true;
        }

        Set<?extends Element> elements = roundEnv.getElementsAnnotatedWith(MyAnnotation.class);
        if (elements == null || elements.isEmpty()) {
            info(">>> elements is null... <<<");
            return true;
        }
        for (Element annotationElement:elements) {
            if (annotationElement.getKind() != ElementKind.CLASS) {
                error(annotationElement, "Only classes can be annotated with @%s", MyAnnotation.class.getSimpleName());
                return true;
            }

            analysisAnnoation(annotationElement);
        }

        return false;
    }
    private void analysisAnnoation(Element classElement) {
        MyAnnotation annotation = classElement.getAnnotation(MyAnnotation.class);
        String name = annotation.name();

        String newClassName = name;
        StringBuilder builder = new StringBuilder();
        builder.append("package com.xxxx.annotation;\n\n")
                .append("public class ")
                .append(newClassName)
                .append("{\n\n")
                .append("\tpublic String getMessage() {\n")
                .append("\t\treturn \"")
                .append(name)
                .append("!\\n")
                .append("\";\n")
                .append("\t}\n")
                .append("}\n");

        try {
            JavaFileObject source = mFiler.createSourceFile(newClassName);
            Writer write = source.openWriter();
            write.write(builder.toString());
            write.flush();
            write.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private void info(String msg, Object... args) {
        mMessager.printMessage(Diagnostic.Kind.NOTE, String.format(msg, args));
    }
    private void error(Element e, String msg, Object... args) {
        mMessager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e);
    }
}

@AutoService 注册自定义注解处理器

gradle增加依赖

apply plugin: 'java-library'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.auto.service:auto-service:1.0-rc2'
}

sourceCompatibility = "1.7"
targetCompatibility = "1.7"

 

3. 使用

配置gradle


android {
compileSdkVersion 27
defaultConfig {
applicationId "com.pax.annotationprocessor"
minSdkVersion 22
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath = true
}
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(":compile")
}
 

增加注解

@MyAnnotation(name = "MyAnn")
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        com.xxxx.annotation.MyAnn myAnn = new MyAnn();
        Log.i("TAG", myAnn.getMessage());
    }
}

 

运行app时报错如下:

Failed to find byte code for javax/annotation/processing/AbstractProcessor

 处理方法:

File/Settings/Build/Instant Run

 

posted @ 2018-08-24 10:10  来错人间的幽魂  阅读(1454)  评论(0编辑  收藏  举报