apt-注解开发-3-自定义processor
来源:互联网 发布:关于网络的流行语 编辑:程序博客网 时间:2024/04/29 07:56
自定义processor
- [0]创建一个java module 命名为apt 在gradle中引入
apply plugin: 'java'dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.google.auto.service:auto-service:1.0-rc2' compile 'com.squareup:javapoet:1.7.0' compile project(':annotation')//定义的注解 用于搜索该项目中定义的注解 sourceCompatibility = 1.7 targetCompatibility = 1.7}
- [1]定义注解信息类 方便处理注解元素
public class BindViewField { //可用的注解元素 private VariableElement variableElement; //view的id 我们自己的id private int mResId; public BindViewField(Element element) { if (element.getKind()!= ElementKind.FIELD){ //在定义注解时 我们限制的 @Target(ElementType.FIELD) throw new IllegalArgumentException( "\"Only fields can be annotated with @%s\",\n" + " BindView.class.getSimpleName())"); } variableElement = (VariableElement) element; //解析注解类 获取注解信息 LzfBindView bindView=variableElement.getAnnotation(LzfBindView.class); mResId=bindView.value(); <!-- @Target(ElementType.FIELD) @Retention(RetentionPolicy.CLASS) public @interface LzfBindView { int value();//既是这里的value view的id } --> if (mResId<0){ throw new IllegalArgumentException( String.format("value() in %s for field %s is not valid !", LzfBindView.class.getSimpleName(), variableElement.getSimpleName())); } } /** * 获取变量名称 * * @return */ Name getFieldName() { return variableElement.getSimpleName(); } /** * 获取变量id * * @return */ int getResId() { return mResId; } /** * 获取变量类型 * * @return */ TypeMirror getFieldType() { return variableElement.asType(); }}
-[2]定义文件创建的规则
public class AnnotationUtils { private static class TypeUtil{ //包名 类名 static final ClassName BINDER=ClassName.get("lzf.api","ViewBinder"); static final ClassName FINDER=ClassName.get("lzf.api","ViewFinder"); } private TypeElement typeElement;//获取类型 private ArrayList<BindViewField> mFields;//注解元素 private Elements elements; public AnnotationUtils(TypeElement typeElement, Elements elements) { this.typeElement = typeElement; this.elements = elements; mFields=new ArrayList<>(); } void addField(BindViewField field){ mFields.add(field); } JavaFile generateFile(){ //生成方法 MethodSpec.Builder bindViewMethod = MethodSpec.methodBuilder("bindView") .addModifiers(Modifier.PUBLIC)//方法权限 .addAnnotation(Override.class)//给方法添加注解 .addParameter(TypeName.get(typeElement.asType()), "host")//方法内参数类型 参数名称 .addParameter(TypeName.OBJECT, "source") .addParameter(TypeUtil.FINDER, "finder"); for (BindViewField field : mFields) { // find views bindViewMethod.addStatement("host.$N = ($T)(finder.findView(source, $L))", field.getFieldName(), ClassName.get(field.getFieldType()), field.getResId()); } //解绑 MethodSpec.Builder unBindViewMethod = MethodSpec.methodBuilder("unBindView") .addModifiers(Modifier.PUBLIC) .addParameter(TypeName.get(typeElement.asType()), "host") .addAnnotation(Override.class); for (BindViewField field : mFields) { unBindViewMethod.addStatement("host.$N = null", field.getFieldName()); } //generaClass 创建类 TypeSpec injectClass = TypeSpec.classBuilder(typeElement.getSimpleName() + "$$ViewBinder")//类名 .addModifiers(Modifier.PUBLIC)//类修饰符 .addSuperinterface(ParameterizedTypeName.get(TypeUtil.BINDER, TypeName.get(typeElement.asType())))//实现的接口 泛型参数类型 .addMethod(bindViewMethod.build()) .addMethod(unBindViewMethod.build()) .build(); String packageName = elements.getPackageOf(typeElement).getQualifiedName().toString();//文件目录 return JavaFile.builder(packageName, injectClass).build(); }}
-[3]自定义processor
@AutoService(Processor.class)public class MyClassProcessor extends AbstractProcessor { private Filer filer;//文件操作类 private Elements elements; private Messager messager; private Map<String,AnnotationUtils> annotationUtilsMap; @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); filer=processingEnv.getFiler(); elements=processingEnv.getElementUtils(); annotationUtilsMap=new TreeMap<>(); } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { annotationUtilsMap.clear(); //获取注解信息 processBindView(roundEnv); for (AnnotationUtils annotationUtils:annotationUtilsMap.values()) { try { //将所有的注解工具类都写成文件 //多个activity都有注解使用 会产生多个注解工具类 每个工具类将生成一个文件 annotationUtils.generateFile().writeTo(filer); } catch (IOException e) { e.printStackTrace(); error("Generate file failed, reason: %s", e.getMessage()); } } return true; } private void processBindView(RoundEnvironment environment){ for (Element e : environment.getElementsAnnotatedWith(LzfBindView.class)) { //environment.getElementsAnnotatedWith(LzfBindView.class) //获取所有lzfbindview注解的元素 //创建注解工具类 AnnotationUtils annotationUtils=getAnnotationUtils(e); //获取注解元素信息 BindViewField bindViewField=new BindViewField(e); //将注解信息添加到注解工具类 annotationUtils.addField(bindViewField); } } private AnnotationUtils getAnnotationUtils(Element e){ TypeElement typeElement= (TypeElement) e.getEnclosingElement(); String fullName=typeElement.getQualifiedName().toString(); AnnotationUtils annotationUtils=annotationUtilsMap.get(fullName); if (annotationUtils==null){ annotationUtils=new AnnotationUtils(typeElement,elements); annotationUtilsMap.put(fullName,annotationUtils); } return annotationUtils; } private void error(String msg, Object... args) { messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args)); } @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latestSupported(); } @Override public Set<String> getSupportedAnnotationTypes() { Set<String> types=new LinkedHashSet<>(); types.add(LzfBindView.class.getCanonicalName()); return types; }}
感谢
http://www.cnblogs.com/whoislcj/p/6168641.html
阅读全文
0 0
- apt-注解开发-3-自定义processor
- Annotation注解APT(二):自定义注解
- apt-注解开发-4-使用
- Java中实现自定义的注解处理器(Annotation Processor)
- apt 注解开发-1-定义注解
- apt-注解开发-2-定义操作api
- 自定义注解开发
- annotation processor tool(apt)的套路
- 注解处理工具apt
- 【java开发系列】—— 自定义注解
- 【java开发系列】—— 自定义注解
- Android如何开发自定义编译时注解
- 【java开发系列】—— 自定义注解
- 【java开发系列】—— 自定义注解
- Android开发技巧之使用自定义注解
- 【Java-Spring开发】aop注解 自定义切面的注解写法
- 自定义注解,自定义Result的整合开发实例
- Android开发-自定义view-入门级自定义view全注解
- SWOT分析方法
- LDD3源码分析之时间与延迟操作
- ssm框架中web.xml 中 设置是否启用异步支持 报错
- 判断远程图片是否存在
- My First Blog
- apt-注解开发-3-自定义processor
- nyoj-20大数阶乘
- geotools判断一个点是否在多边形上
- 蓝桥杯-第七届蓝桥杯java B组决赛 路径之谜
- struts2 json 注解
- C++的一些不错开源框架,可以学习和借鉴
- html5<canvas模拟三维图形>(旋转的正方体)
- Jquery工具
- C语言命名规则