Android自定义注解

Android自定义注解,第1张

概述1、元注解 概念:用来定义其他注解的注解,自定义注解的时候,需要使用它来定义我们的注解。 在jdk1.5之后提供了java.lang.annotation来支持注解功能 常见的四种元注解有:@Target(目标, 注解可以使用的地方,参数是一个ElementType枚举)@Retention (保持性,描述注解 1、元注解 概念:用来定义其他注解的注解,自定义注解的时候,需要使用它来定义我们的注解。 在jdk 1.5之后提供了 java.lang.annotation 来支持注解功能 常见的四种元注解有 :@Target (目标,  注解可以使用的地方,参数是一个ElementType 枚举)@Retention  (保持性, 描述注解的生命周期  ) @inherited ( 可继承的, 参数true or false ,表示是否允许子类继承该注解,默认false)@document (文档化,表明注解可以被javadoc 此类工具文档化) 1.1 @Target@Target ElementType 枚举类型 
ElementType.Type接口、类、注解、枚举
ElementType.FIELD字段、枚举常量
ElementType.METHOD方法
ElementType.ParaMETER方法参数
ElementType.CONSTRUCOTOR构造函数
ElementType.LOCAL_VARIABLE局部变量
ElementType.ANNOTATION_TYPE注解
Element.PACKAGE
1.2 @Retention  用于描述注解的生命周期, 注解在什么地方使用有效参数 RetentionPolicy 枚举对象 
RetentionPolicy.soURCE源文件,当java文件被编译成class文件时,注解失效
RetentionPolicy.CLASS注解存在class 文件,当jvm 加载class文件时,注解生效,默认指定的参数
RetentionPolicy.RUNTIME注解保存到class文件,jvm加载class文件后,依然有效
周期有效性, RUNTIME > CLASS > SOURCE 1.3 @document  标记自定义注解可被javadoc 此类文档化 1.4 @inherited @inherited    表明我们标记的注解是被继承的,如果一个父类使用@inherited 修饰的注解,则允许子类继承该父类的注解 二、自定义注解 步骤:1、申明注解,确定注解的运行生命周期、目标、参数2、注解解析:找到被注解类的方法、属性。添加自定义注解的一些 *** 作 案例1、注解创建对象2.1申明注解autocreateObject
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自定义注解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1115945.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存