ElementType.Type | 接口、类、注解、枚举 |
ElementType.FIELD | 字段、枚举常量 |
ElementType.METHOD | 方法 |
ElementType.ParaMETER | 方法参数 |
ElementType.CONSTRUCOTOR | 构造函数 |
ElementType.LOCAL_VARIABLE | 局部变量 |
ElementType.ANNOTATION_TYPE | 注解 |
Element.PACKAGE | 包 |
RetentionPolicy.soURCE | 源文件,当java文件被编译成class文件时,注解失效 |
RetentionPolicy.CLASS | 注解存在class 文件,当jvm 加载class文件时,注解生效,默认指定的参数 |
RetentionPolicy.RUNTIME | 注解保存到class文件,jvm加载class文件后,依然有效 |
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/*** author: rexkell* explain:*/@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface autocreateObject {}
2.2解析注解
import java.lang.reflect.Constructor;import java.lang.reflect.FIEld;import java.lang.reflect.InvocationTargetException;/*** author: rexkell* explain:*/public class autocreateProcess {public static voID bind(final Object object){Class parentClass=object.getClass();FIEld[] fIElds= parentClass.getFIElds();for (FIEld fIEld: fIElds){autocreateObject autocreateObject= fIEld.getAnnotation(autocreateObject.class);if (autocreateObject!=null){fIEld.setAccessible(true);try {Class<?> autocreateClass= fIEld.getType();Constructor autocreateConstructor= autocreateClass.getConstructor();fIEld.set(object,autocreateConstructor.newInstance());} catch (NoSuchMethodException e) {e.printstacktrace();}catch (illegalaccessexception e){e.printstacktrace();}catch (InvocationTargetException e){e.printstacktrace();}catch (InstantiationException e){e.printstacktrace();}}}}}
@autocreateObject
Students students;
//创建对象
autocreateProcess.bind(this);
3、模拟bindVIEwID
3.1、创建一个java Module
implementation 'com.squareup:javapoet:1.9.0'implementation 'com.Google.auto.service:auto-service:1.0-rc2'
3.2 申明注解
import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/*** author: rexkell* explain:*/@Target(ElementType.FIELD)@Retention(RetentionPolicy.CLASS)public @interface BindVIEw {int value() default -1;}
3.3 解析注解
import androID.app.Activity;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;/*** author: rexkell* explain:*/public class MyBindVIEw {private static Map<Class, Method> classMethodMap=new HashMap<>();public static voID bind(Activity target){if (target!=null){Method method = classMethodMap.get(target.getClass());try {if (method==null){//获取编译生成的注解类String bindClassname= target.getPackagename()+".Bind"+target.getClass().getSimplename();Class bindClass=Class.forname(bindClassname);method=bindClass.getmethod("bindVIEw",target.getClass());classMethodMap.put(target.getClass(),method);}method.invoke(null,target);} catch (Exception e) {e.printstacktrace();}}}}
由于是编译时产生的注解,需要通过 extends AbstractProcessor 来实现
import com.Google.auto.service.autoService;import com.squareup.javapoet.Classname;import com.squareup.javapoet.Javafile;import com.squareup.javapoet.MethodSpec;import com.squareup.javapoet.Typename;import com.squareup.javapoet.typespec;import java.io.IOException;import java.util.HashMap;import java.util.HashSet;import java.util.Locale;import java.util.Map;import java.util.Set;import javax.annotation.processing.AbstractProcessor;import javax.annotation.processing.ProcessingEnvironment;import javax.annotation.processing.Processor;import javax.annotation.processing.RoundEnvironment;import javax.annotation.processing.SupportedSourceVersion;import javax.lang.model.sourceVersion;import javax.lang.model.element.Element;import javax.lang.model.element.ModifIEr;import javax.lang.model.element.TypeElement;import javax.lang.model.util.Elements;/*** author: rexkell* explain:*/@autoService(Processor.class)@SupportedSourceVersion(SourceVersion.RELEASE_7)public class BindProcess extends AbstractProcessor {private Elements mElementsUtil;private Map<TypeElement,Set<Element>> mBindVIEwElems;@OverrIDepublic synchronized voID init(ProcessingEnvironment processingEnv) {super.init(processingEnv);mElementsUtil=processingEnv.getElementUtils();mBindVIEwElems=new HashMap<>();}@OverrIDepublic Set<String> getSupportedAnnotationTypes() {//添加需要解析的自定义注解类Set<String> types=new HashSet<>();types.add(BindVIEw.class.getCanonicalname());types.add(BindLayout.class.getCanonicalname());return types;}@OverrIDepublic boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {System.out.println("Process start!");initBindElems(roundEnv.getElementsAnnotateDWith(BindVIEw.class));generateJavaClass();System.out.println("Process finish!");return true;}//初始化绑定的控件private voID initBindElems(Set<? extends Element> bindElems){for (Element bindElem : bindElems){TypeElement enclosedElem=(TypeElement) bindElem.getEnclosingElement();Set<Element> elems=mBindVIEwElems.get(enclosedElem);if (elems==null){elems=new HashSet<>();mBindVIEwElems.put(enclosedElem,elems);System.out.println(enclosedElem.getSimplename());}elems.add(bindElem);System.out.println("Add bind elem "+bindElem.getSimplename());}}private voID generateJavaClass(){//生成Bind+Classname+.class 文件,文件内容实现findVIEwByIDfor (TypeElement enclosedElem: mBindVIEwElems.keySet()){MethodSpec.Builder methodSpesBuilder = MethodSpec.methodBuilder("bindVIEw").addModifIErs(ModifIEr.PUBliC, ModifIEr.STATIC).addParameter(Classname.get(enclosedElem.asType()),"activity").returns(Typename.VOID);BindLayout bindLayoutAnno =enclosedElem.getAnnotation(BindLayout.class);if (bindLayoutAnno!=null){methodSpesBuilder.addStatement(String.format(Locale.US,"activity.setContentVIEw(%d)",bindLayoutAnno.value()));}for (Element bindElem : mBindVIEwElems.get(enclosedElem)){methodSpesBuilder.addStatement(String.format(Locale.US,"activity.%s=(%s)activity.findVIEwByID(%d)",bindElem.getSimplename(),bindElem.asType(),bindElem.getAnnotation(BindVIEw.class).value()));}typespec typespec=typespec.classBuilder("Bind"+enclosedElem.getSimplename()).superclass(Typename.get(enclosedElem.asType())).addModifIErs(ModifIEr.FINAL,ModifIEr.PUBliC).addMethod(methodSpesBuilder.build()).build();Javafile file = Javafile.builder(getPackagename(enclosedElem),typespec).build();try {file.writeto(processingEnv.getfiler());} catch (IOException e) {e.printstacktrace();}}}private String getPackagename(TypeElement typeElement){return mElementsUtil.getPackageOf(typeElement).getQualifIEdname().toString();}}
3.4 在需要使用bindVIEwID 注解中引入模块。
@BindVIEw(R.ID.edt_longitude) EditText edtLongitude;@OverrIDeprotected voID onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SharedPreferences sharedPreferences= this.getSharedPreferences("theme",MODE_PRIVATE);int themeID=sharedPreferences.getInt("themeID",2);if (themeID==1){settheme(R.style.BaseAppthemeNight);}else if (themeID==0){settheme(R.style.Apptheme);}setContentVIEw(R.layout.activity_main);MyBindVIEw.bind(this);}
总结
以上是内存溢出为你收集整理的Android自定义注解全部内容,希望文章能够帮你解决Android自定义注解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)