Android注解原理与常用注解框架
来源:互联网 发布:vans淘宝有正品吗 编辑:程序博客网 时间:2024/05/29 12:00
Android注解原理与常用注解框架
- 注解基本介绍
- 编写注解
- Android注解框架
注解的基本介绍
注解的定义
能够添加到 Java 源代码的语法元数据。类、方法、变量、参数、包都可以被注解,可用来将信息元数据与程序元素进行关联,常见的注解如@Override, @Deprecated。元注解
元注解是基本注解,所有的自定义注解都将会用到元注解,元注解主要有如下四个:- @Retention
这个注解表示注解的保留方式,有如下三种:- SOURCE:只保留在源码中,不保留在class中,同时也不加载到虚拟机中
- CLASS:保留在源码中,同时也保留到class中,但是不加载到虚拟机中
- RUNING:保留到源码中,同时也保留到class中,最后加载到虚拟机中
- SOURCE:只保留在源码中,不保留在class中,同时也不加载到虚拟机中
具体的区别如下:
运行时注解就是就是运行时运用反射,动态获取对象、属性、方法等,一般的IOC框架就是这样,可能会牺牲一点效率。
编译时注解就是在程序编译时根据注解进行一些额外的操作,大名鼎鼎的ButterKnife运用的就是编译时注解,ButterKnife在我们编译时,就根据注解,自动生成了一些辅助类。要玩编译时注解呢,你得先依赖apt,r然后自己写一个类继承AbstractProcessor,重写process方法,在里面实现如何把配置或注解的信息变成所需要的类。
@Target
这个注解表示注解的作用范围,主要有如下:ElementType.FIELD 注解作用于变量
ElementType.METHOD 注解作用于方法
ElementType.PARAMETER 注解作用于参数
ElementType.CONSTRUCTOR 注解作用于构造方法
ElementType.LOCAL_VARIABLE 注解作用于局部变量
ElementType.PACKAGE 注解作用于包
@Inherited
是否可以被继承,默认为 false
@Documented
是否会保存到 Javadoc 文档中
基本注解
java中常用的注解有如下三个- @Override: 表示该方法是重写父类中的方法,编译的时候会检查该方法,如果这个方法不是父类中存在的将会报错
- @Deprecated: 表示该方法时已经过时的,表示该方法有风险或者有更好的替代方法
- @SuppressWarnings: 表示在编译的时候忽略某种错误,如版本检查等
编写注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnonation { String name() default ""; int Id() default 0; }
注解关键字时@interface,然后上面标注为元注解,表示只能修饰方法并且加载到虚拟机中,里面时这个注解所具有的属性,name, id,我们在给方法加注解的时候设置相应的值。
@TestAnnonation(name = "android" , Id = 1) private void testAnno(){ }
上面我们在一个方法上面添加注解,然后我们通过下面的方法将这个注解打印出来
private void outputAnnoDetail(Class clazz){ Method [] methods = clazz.getDeclaredMethods(); for(Method method : methods) { TestAnnonation testAnnonation = method.getAnnotation(TestAnnonation.class); if (testAnnonation != null) { Log.d("anonation", "name------>" + testAnnonation.name() + "------>Id------>" + testAnnonation.Id()); } } }
上面的打印结果就是
name------>android------>Id------>1
这是一个运行时注解,注解的作用就是标记一个可以被识别的作用域,可以被其他地方获取解释或者被编译机识别等作用。
Android注解框架
- ButterKnife
ButterKnife注解框架是大家常用的注解框架,它主要作用是绑定View并且绑定View常用的监听事件,下面是其中一个注解
@Retention(CLASS) @Target(FIELD)public @interface BindView { /** View ID to which the field will be bound. */ @IdRes int value();}
通过上面的代码可以看出,ButterKnife的注解保留方式为CLASS模式,也就是会保留到class中但是不会背加载到虚拟机中,这个时候我们就要看下它的AbstractProcessor,一般标注为Class的都会重写AbstractProcessor类,这样在虚拟机进行编译的时候就会做相应的处理。
主要看一下几个方法:
@Overridepublic Set<String> getSupportedAnnotationTypes() { Set<String> types = new LinkedHashSet<>(); for (Class<? extends Annotation> annotation : getSupportedAnnotations()) { types.add(annotation.getCanonicalName()); } return types; } private Set<Class<? extends Annotation>> getSupportedAnnotations() { Set<Class<? extends Annotation>> annotations = new LinkedHashSet<>(); annotations.add(BindArray.class); annotations.add(BindBitmap.class); annotations.add(BindBool.class); annotations.add(BindColor.class); annotations.add(BindDimen.class); annotations.add(BindDrawable.class); annotations.add(BindFloat.class); annotations.add(BindInt.class); annotations.add(BindString.class); annotations.add(BindView.class); annotations.add(BindViews.class); annotations.addAll(LISTENERS); return annotations; }
上面的方法主要表明会处理哪些注解
@Overridepublic boolean process(Set<? extends TypeElement> elements, RoundEnvironment env) { Map<TypeElement, BindingSet> bindingMap = findAndParseTargets(env); for (Map.Entry<TypeElement, BindingSet> entry : bindingMap.entrySet()) { TypeElement typeElement = entry.getKey(); BindingSet binding = entry.getValue(); JavaFile javaFile = binding.brewJava(sdk); try { javaFile.writeTo(filer); } catch (IOException e) { error(typeElement, "Unable to write binding for type %s: %s", typeElement, e.getMessage()); } } return true; }
然后就是在编译的时候的具体处理过程,这个过程主要时先找到并解析注解,然后生成java文件,这样在虚拟机真正执行的时候就不用去查找和解析,也就不会耗时了。
* EventBus
EventBus是使用运行时注解,主要的作用是在运行的时候会去查找所有被注解的方法,然后再去解析注解。运行时注解会影响程序的性能,毕竟在运行的时候有一个查找的过程,所以运行时注解的作用一般是标记一个作用区。
- Android注解原理与常用注解框架
- Android框架中常用的反射与注解
- Android:注解型框架原理浅析
- Android面试题-注解框架实现原理
- SpringMVC原理与SpringMVC常用注解
- SpringMVC核心原理与常用注解解释
- Android 注解原理
- Android butterknife注解框架
- Android注解框架对比
- Android ButterKnife注解框架
- Android 自定义注解框架
- Android注解框架对比
- Android:注解框架对比
- Android注解框架对比
- Android注解框架对比
- Android注解框架AndroidAnnotations
- android注解框架--ButterKnife
- Android注解框架
- 寄存器、CACHE、RAM、ROM、flash相关概念整理
- Qt之 Testlib学习(1)
- C++ 调用 Python 初探(一)
- Weex & ReactNative & JSPatch
- php返回json数据中文显示的问题
- Android注解原理与常用注解框架
- vim复制
- android 学习随笔一(配置调试与基础)
- Android性能优化总结
- 第12章 5竞猜
- java性能优化笔记(一)概述
- Description Resource Path Location Type AndroidManifest.xml file missing!
- java 使用拦截器统计每个http请求的响应时间
- detached entity passed to persist 错误的引起的原因和解决办法