吐槽
Android开发中,我们经常写一大坨findViewById(int)类似代码,既浪费时间代码又不美观,所以很多人选择使用第三方注解式绑定库butterknife,其实Android注解式绑定控件,没你想象的那么难,我们自己也可以实现,那就开始动手吧。
注解
什么是注解?注解是用来干嘛的?
从jdk1.5开始,Java提供了注解的功能,允许开发者定义和使用自己的注解类型,该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的class文件和一个注解处理工具组成。首先,你需要接受一个关键字@interface,它可不是接口定义关键字,是Java中表示声明一个注解类的关键字。使用@interface表示我们已经继承了java.lang.annotation.Annotation类,这是一个注解的基类接口,就好像Object类,现在你只需要知道它的存在就行了。还有一条规定:在定义注解时,不能继承其他的注解或接口。那么,这就是最简单的一个注解类
|
|
@Target的意思是我们注解作用的目标,这里是ElementType.FIELD,也就是作用于字段的
ElementType的类型有以下几种:
- CONSTRUCTOR:用于描述构造器
- FIELD:用于描述字段
- LOCAL_VARIABLE:用于描述局部变量
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述参数
- TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention的意思是注解的运行级别
RetentionPolicy的类型有以下几种
- SOURCE:在源文件中有效(即源文件保留)
- CLASS:在class文件中有效(即class保留)
- RUNTIME:在运行时有效(即运行时保留)
使用注解
注解类型是不能直接new对象的,那么这个BindView对象从哪里来呢?
这时就需要用到Java的反射机制。我们知道,每一个继承自Object类的类都会继承一个getClass()方法下面看一下这个方法的原型:
这个方法返回的是该类的Class对象,Class中有一个方法叫getDeclaredFields(),是用来返回这个类的全部字段,返回类型是Field[]
通过Field对象的getAnnotation(Class<?>)方法,我们可以获取到任何一个Class的对象,通过getAnnotation(Class<?>),我们就可以获取到BindView的对象了。
|
|
Android项目中应用
定义好了注解,如果我们直接来使用,是没有任何效果的,因为注解只是一段代码,并没有关联上我们的控件,所以我们要编写一个工具类来做关联
|
|
当我们需要使用注解的时候,我们只需要在定义View的时候,在View的字段上添加对应的注解,把Id传入,然后在onCreate方法中调用上面这个工具类的方法即可。
几点说明:
- 如果注解中的值不是value,那么在进行注解是时候,需要给出对应的值的名字,假如我们在注解中做了如下定义:12345678@Target(FIELD)@Retention(RUNTIME)public @interface BindView {/*** View ID to which the field will be bound.*/@IdRes int id();}
那么在注解的时候,需要这样:
2 .使用注解的时候,句末不能加”;”
- Android中的注解式绑定控件(也是所谓的IOC控制反转在安卓中的一种应用)其实本质的使用就是Java基础中反射的使用。值得一提的是,反射执行的效率是很低的.