Android 自定义注解
来源:互联网 发布:穿越火线fps优化器 编辑:程序博客网 时间:2024/06/04 21:15
一。按注解处理方式分类
1.1 运行时处理 这个是编译器默认的做法,编译器会通过class文件,逐个逐个的遍历class的属性和方法,即运行时处理1.2 编译时处理编译器会在编译的时候,将注解的属性引入在进行编译
二。基本概念
2.1元注解 @desc{用于修饰定义自定义注解的注解} **@Target**:表明该自定义注解应该用于什么地方 ElemenetType.CONSTRUCTOR----构造器声明 ElemenetType.FIELD ----域声明(包括 enum 实例) ElemenetType.LOCAL_VARIABLE---- 局部变量声明 ElemenetType.METHOD----方法声明 ElemenetType.PACKAGE ---- 包声明 ElemenetType.PARAMETER ----参数声明 ElemenetType.TYPE---- 类,接口(包括注解类型)或enum声明 **@Retention**:@desc{表明该自定义注解的生命周期} RetentionPolicy.SOURCE ----注解只会保留在源文件中(JAVA code),将被编译器丢弃 RetentionPolicy.CLASS ----注解保留在 class 文件中,加载到 JVM 时会被JVM丢弃 RetentionPolicy.RUNTIME VM----注解将保留在运行期,因此可以通过反射机制读取注解的信息。 **@Documented:**@desc{表明该自定义注解可以被 javadoc 工具提取到文档中}**@Inherited:**@desc{允许子类继承父类注解}
三。自定义注解实现
3.1运行时反射 Reflect @code: public class InjectActivity extends AppCompatActivity {private int mLayoutId = -1;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); displayInjectLayout(); displayInjectView();}/** * 解析注解view id */private void displayInjectView() { if (mLayoutId <=0){return ;} Class<?> clazz = this.getClass();//获取该类的 Class 对象 Field[] fields = clazz.getDeclaredFields();//获得声明的成员变量 for (Field field : fields) { //判断是否有注解 try { if (field.getAnnotations() != null) { if (field.isAnnotationPresent(ViewInject.class)) {//如果属于这个注解 //为这个控件设置属性 field.setAccessible(true);//允许修改反射属性 ViewInject inject = field.getAnnotation(ViewInject.class); field.set(this, this.findViewById(inject.value())); } } } catch (Exception e) { Log.e("wusy", "not found view id!"); }throw new InterruptedException("not found view id!"); }}/** * 注解布局Layout id */private void displayInjectLayout() { Class<?> clazz = this.getClass(); if (clazz.getAnnotations() != null){ if (clazz.isAnnotationPresent(LayouyInject.class)){ LayouyInject inject = clazz.getAnnotation(LayouyInject.class); mLayoutId = inject.value(); setContentView(mLayoutId); } }}
}
3.2编译时 AnnotationProcessor 3.2.1Android程序的编译流程 标准 java 编译方式 javac(*.java—>*.class){ ProGuard }—>dx(*.class—>*.dex) 1—— javac 工具将 java源代码编译成 .class(java 字节码) 2—— ProGuard 工具读取 Proguard 配置,对 class 文件做压缩和忽略混淆,输出 Proguard mapping 3—— dx 工具将.class文件转化成 classes.dex,若单个 dex 文件方法数超过64K。开启多分包—》classes1.dex ,classes2.dex。。。。。 jack 编译方式(java Android compiler kit) Jack(.java—>.jack—>.dex) 参考文章@link{ http://taobaofed.org/blog/2016/05/05/new-compiler-for-android/ } 3.2.2 APT 插件(Annotation Processing Tool) 注解处理器是 javac 内置的一个工具,用于在编译时期扫描和处理注解信息。一个特定的 APT 接收一个 java 源代码或者已编译的 class 字节码作为输入,然后输出一些文件(一般是 java 文件)。使用 apt 可以动态生成代码逻辑,但是 apt 只能生成新的 java 类文件,而不能在旧的 java 类上做修改,所有apt生成的 java 类会和其他 java 代码一起被编译。 3.3.3实现自定义注解处理器 1.新建一个 module,必须设置为 java Library,否则找不到 AbstractProcessor 2.自定义注解处理器,继承@link{ javax.annotation.processing.AbstractProcessor } 虚处理器 ![这里写图片描述](http://img.blog.csdn.net/20170627180911830?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hyaXNtYTY2Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 3.3.4.声明注解处理器{注册到 JVM} 1、在 processors 库的 main 目录下新建 resources 资源文件夹; 2、在 resources文件夹下建立 META-INF/services 目录文件夹; 3、在 META-INF/services 目录文件夹下创建 javax.annotation.processing.Processor 文件; 4、在 javax.annotation.processing.Processor 文件写入注解处理器的全称,包括包路径; 或者 使用 Google 的 AutoService 注解,AutoService注解处理器是Google开发的,用来生成 META-INF/services/javax.annotation.processing.Processor 文件的,你只需要在你定义的注解处理器上添加 @AutoService(Processor.class) compile 'com.google.auto.service:auto-service:1.0-rc2’
在处理器里面添加注解@AutoService(Processors.class)
3.3.5关于annotations 和 processors 库依赖的问题 a.app 直接依赖 annotations 和 processors 两个 module compile project(':annotations') compile project(':processors') b.android-apt: app 只依赖 annotations 模块,不用依赖 processors 模块 ![这里写图片描述](http://img.blog.csdn.net/20170627191527434?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hyaXNtYTY2Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) c.annotationProcessor: 注:一定要移除 apt 的相关配置,不然会冲突,导致 ap 失效 ![这里写图片描述](http://img.blog.csdn.net/20170627191635497?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hyaXNtYTY2Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
阅读全文
4 0
- Android 自定义注解框架
- Android中的自定义注解
- Android 自定义注解
- Android 自定义注解详解
- Android 自定义注解
- 自定义Android 注解
- Android进阶之自定义注解
- Android ViewUtils注解框架自定义
- Android进阶之自定义注解
- 学习如何自定义Android注解
- Android中的自定义注解(反射实现-运行时注解)
- Android中的自定义注解(反射实现-运行时注解)
- Android中的自定义注解(反射实现-运行时注解)
- Android中的自定义注解(反射实现-运行时注解)
- Android自定义注解与注解器实现点击事件绑定
- Android中的自定义注解(反射实现-运行时注解)
- android 自定义注解 通过反射获取注解属性值
- android自定义注解初始化布局控件(二)
- 如何保护你的隐私(一)
- 数据字典设计实现缓存
- 前端入门篇
- 深入浅析同源策略和跨域访问
- 1Z0-051 9.Which statement is true regarding the INTERSECT operator?
- Android 自定义注解
- Jdk的动态代理
- Presto初步认识
- php批量判断参数不能为空
- 数据维护
- 对象存储之二:实践
- 内部类与向上转型
- 【深入Spring】——Tiny Spring IoC(二)BeanClass
- 数据库事务的四大特性以及事务的隔离级别