1 ElementKind
如何判断Element的类型呢,需要用到ElementKind,ElementKind为元素的类型,元素的类型判断不需要用instanceof去判断,而应该通过getKind()去判断对应的类型
类型--说明
PACKAGE 包
ENUM 枚举
CLASS 类
ANNOTATION_TYPE 注解
INTERFACE 接口
ENUM_CONSTANT 枚举常量
FIELD 字段
PARAMETER 方法参数
LOCAL_VARIABLE 局部变量
METHOD 方法
CONSTRUCTOR 构造方法
TYPE_PARAMETER 类型参数
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD,ElementType.PACKAGE,ElementType.PARAMETER})
@Retention(RetentionPolicy.CLASS)
public @interface ClassTarget {
String name() default "";
int value() default 0;
}
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes("com.ldx.annotationlib.ClassTarget")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class AptProcessor4 extends AbstractProcessor {
private Filer mFilerUtils;
private Types mTypesUtils;
private Elements mElementsUtils;
private Messager mMessager;
private Map mOptionMap;
private ArrayList mElementList;
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
mFilerUtils = processingEnv.getFiler();
mTypesUtils = processingEnv.getTypeUtils();
mElementsUtils = processingEnv.getElementUtils();
mMessager = processingEnv.getMessager();
mOptionMap = processingEnv.getOptions();
mElementList = new ArrayList<>();
}
@Override
public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
if (set != null && set.size() > 0){
Set extends Element> elements = roundEnvironment.getElementsAnnotatedWith(ClassTarget.class);
for (Element element : elements) {
ElementKind kind = element.getKind();
if (kind == ElementKind.CLASS){
TypeElement typeElement = (TypeElement) element;
mMessager.printMessage(Diagnostic.Kind.NOTE,"=============Class======"+typeElement.getSimpleName().toString());
}else if (kind == ElementKind.FIELD){
VariableElement variableElement = (VariableElement) element;
mMessager.printMessage(Diagnostic.Kind.NOTE,"=============Field======"+variableElement.getSimpleName().toString());
}else if (kind == ElementKind.METHOD){
ExecutableElement executableElement = (ExecutableElement) element;
mMessager.printMessage(Diagnostic.Kind.NOTE,"=============Method======"+ executableElement.getSimpleName());
}else if (kind == ElementKind.PARAMETER){
mMessager.printMessage(Diagnostic.Kind.NOTE,"=============方法参数======"+ element.getSimpleName());
} else {
mMessager.printMessage(Diagnostic.Kind.NOTE,"=============othertype======"+element.getSimpleName());
}
ClassTarget target = element.getAnnotation(ClassTarget.class);
mMessager.printMessage(Diagnostic.Kind.NOTE,"======name======value======="+target.name()+" "+target.value()+"\n\n");
}
}
return true;
}
return false;
}
}
使用:
import com.ldx.annotationlib.BindView;
import com.ldx.annotationlib.ClassTarget;
import com.ldx.canvasdrawdemo.R;
import com.ldx.injectlib.ViewInject;
@ClassTarget(name = "class1",value = 1)
public class BindViewActivity extends AppCompatActivity {
@ClassTarget(name = "field1",value = 2)
@BindView(R.id.tv1)
public TextView textView1;
@ClassTarget(name = "field2",value = 2)
@BindView(R.id.tv2)
public TextView textView2;
@ClassTarget(name = "field3",value = 2)
@BindView(R.id.tv3)
public TextView textView3;
@ClassTarget(name = "method1",value = 3)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bind_view);
ViewInject.inject(BindViewActivity.this);
if (textView1 != null){
System.out.println("=================="+textView1.toString());
textView1.setText("apt 设置的Text");
}else{
System.out.println("==================没有绑定成功");
}
}
@ClassTarget(name = "method2",value = 3)
private void test(@ClassTarget(name = "show",value = 4) int show){
}
}
结果:
注: =============Class======BindViewActivity
注: ======name======value=======class1 1
注: =============Field======textView1
注: ======name======value=======field1 2
注: =============Field======textView2
注: ======name======value=======field2 2
注: =============Field======textView3
注: ======name======value=======field3 2
注: =============Method======onCreate
注: ======name======value=======method1 3
注: =============Method======test
注: ======name======value=======method2 3
注: =============方法参数======show
注: ======name======value=======show 4
2 TypeKind
TypeKind为类型的属性,类型的属性判断不需要用instanceof去判断,而应该通过getKind()去判断对应的属性
类型 说明
BOOLEAN 基本类型boolean
INT 基本类型int
LONG 基本类型long
FLOAT 基本类型float
DOUBLE 基本类型double
VOID 对应于关键字void的伪类型
NULL null类型
ARRAY 数组类型
PACKAGE 对应于包元素的伪类型
EXECUTABLE 方法、构造方法、初始化
DECLARE 声明类型
package com.ldx.processor;
import com.ldx.annotationlib.ClassTarget;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes("com.ldx.annotationlib.ClassTarget")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class AptProcessor4 extends AbstractProcessor {
private Filer mFilerUtils;
private Types mTypesUtils;
private Elements mElementsUtils;
private Messager mMessager;
private Map mOptionMap;
private ArrayList mElementList;
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
mFilerUtils = processingEnv.getFiler();
mTypesUtils = processingEnv.getTypeUtils();
mElementsUtils = processingEnv.getElementUtils();
mMessager = processingEnv.getMessager();
mOptionMap = processingEnv.getOptions();
mElementList = new ArrayList<>();
}
/* 如何判断Element的类型呢,需要用到ElementKind,
ElementKind为元素的类型,元素的类型判断不需要用instanceof去判断,
而应该通过getKind()去判断对应的类型
类型 说明
PACKAGE 包
ENUM 枚举
CLASS 类
ANNOTATION_TYPE 注解
INTERFACE 接口
ENUM_CONSTANT 枚举常量
FIELD 字段
PARAMETER 方法参数
LOCAL_VARIABLE 局部变量
METHOD 方法
CONSTRUCTOR 构造方法
TYPE_PARAMETER 类型参数*/
@Override
public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
if (set != null && set.size() > 0){
Set extends Element> elements = roundEnvironment.getElementsAnnotatedWith(ClassTarget.class);
for (Element element : elements) {
TypeMirror typeMirror = element.asType();
mMessager.printMessage(Diagnostic.Kind.NOTE,"===========typeMirror======="+typeMirror.toString());
TypeKind typeKind = typeMirror.getKind();
if (typeKind == TypeKind.VOID){
mMessager.printMessage(Diagnostic.Kind.NOTE,"===========VOID======="+typeKind.name().toString());
}else if (typeKind == TypeKind.EXECUTABLE){
mMessager.printMessage(Diagnostic.Kind.NOTE,"===========EXECUTABLE======="+typeKind.name().toString());
}else if (typeKind == TypeKind.DECLARED){
mMessager.printMessage(Diagnostic.Kind.NOTE,"===========DECLARED======="+typeKind.name().toString());
}else if (typeKind == TypeKind.INT){
mMessager.printMessage(Diagnostic.Kind.NOTE,"===========INT======="+typeKind.name().toString());
}else if (typeKind == TypeKind.TYPEVAR){
mMessager.printMessage(Diagnostic.Kind.NOTE,"===========TYPEVAR======="+typeKind.name().toString());
}else {
mMessager.printMessage(Diagnostic.Kind.NOTE,"===========else======="+typeKind.name().toString());
}
}
return true;
}
return false;
}
}
注解声明和使用和上面一致:
结果:
注: ===========typeMirror=======com.ldx.canvasdrawdemo.activity.BindViewActivity
注: ===========DECLARED=======DECLARED
注: ===========typeMirror=======android.widget.TextView
注: ===========DECLARED=======DECLARED
注: ===========typeMirror=======android.widget.TextView
注: ===========DECLARED=======DECLARED
注: ===========typeMirror=======android.widget.TextView
注: ===========DECLARED=======DECLARED
注: ===========typeMirror=======(android.os.Bundle)void
注: ===========EXECUTABLE=======EXECUTABLE
注: ===========typeMirror=======(int)void
注: ===========EXECUTABLE=======EXECUTABLE
注: ===========typeMirror=======int
注: ===========INT=======INT