Android注释开发

从jdk1.5开始java提供了注释功能,允许开发者定义和使用自己的注释类型。
该功能由一个定义注释类型的语法和描述一个注释声明的语法,读取注释的API;一个使用注释修饰的class文件和一个注释处理工具组成。

首先,其语法定义形式为@interface,其含义为声明一个注释类的关键字。

使用@interface表示我们已经继承了java.lang.annotation.Annotation类,这是一个注释的基类接口。就好像Objcet类.
annotation 是注释 注解的意思

其语法还有一条规定:在定义注释时,不能继承其他的注释或接口。

public @interface MyAnnotation{
}

然后通常在使用时我们都会给这个注释类加上两个注释
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
ElementType、RetentionPolicy 是两个枚举类,ElementType.FIELD表示我们需要注释的是一个字段。

ElementType枚举常量摘要
ANNOTATION_TYPE 注释类型声明
CONSTRUCTOR 构造方法声明
FIELD 字段声明
LOCAL_VARIABLE 局部变量声明
METHOD 声明方法
PACKAGE 包声明
TYPE 类接口或枚举声明

RetentionPolicy 枚举常量摘要
CLASS 编译器将把注释记录在类文件中,但在运行时VM不需要保留注释
RUNTIME 编译器将把注释记录在类文件中,在运行时VM将保留注释,因此可以反射性地读取.
SOURCE 编译器要丢弃的注释

使用注释

//声明注释
@Target(Element.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindView{
    public int id();
    public boolean click() default false;
}

使用注释

@BindView(id=R.id.x,click=true) private TextView t;

我们可以看到。除了明显减少了代码量,还使得代码结构更佳清晰.
其中,定义部分的id()表示注释接受一个int类型的数据作为id对应的值
同理,定义部分的click表示接受一个Boolean类型的数据作为click对应的值,还可以设置一个默认值使用default修饰.

处理注释:
我们已经知道了注释怎么定义和使用,接下来就应该知道怎么处理了。
bindView注释可以接受一个int类型的值和一个boolean类型的值.那么这两个值接收了以后如何获取呢?
其实获取的方法很简单就是通过一个bindView类型的对象,调用这个对象来自声明中定义的两个方法->id()或click()方法。

现在有一个问题,注释类型是不能直接new 对象的,那么这个bindView对象从那里来呢?

这是就需要用到Java的反射机制。我们知道每一个继承自object类的类都会继承一个getClass()方法,下面看一下这个方法的原型。

 /**
     * Returns the unique instance of {@link Class} that represents this
     * object's class. Note that {@code getClass()} is a special case in that it
     * actually returns {@code Class<? extends Foo>} where {@code Foo} is the
     * erasure of the type of the expression {@code getClass()} was called upon.
     * <p>
     * As an example, the following code actually compiles, although one might
     * think it shouldn't:
     * <p>
     * <pre>{@code
     *   List<Integer> l = new ArrayList<Integer>();
     *   Class<? extends List> c = l.getClass();}</pre>
     *
     * @return this object's {@code Class} instance.
     */
    public final native Class<?> getClass();

这是一个native方法,根据注释我们知道,这个方法返回的是该类的Class对象,同时也是该类的二进制对象。Class中有一个方法叫getDeclareFields(),是用来返回这个类的全部字段,返回类型是Field[]通过Field对象的getAnnotation(Class

public static void initBindView(Object currentClass,View courceView)
{//通过反射获取到全部属性,反射的字段可能是一个类(静态)字段或实例字段
    Field[] fields=currentClass.getClass.getDeclareFields();
    for(Field fidld:fields)
    {
    BindView bindView=field.getAnnotation(BindView.class);
        if(bindView!=null)
        {
                int viewId=bindView.id();
                boolean clickIs=bindView.click();   
                try{
                        field.getAccessible(true);
                        if(clickIs)
                        {
                            sourceView.findViewById(viewId).setOnClickListener((OnClickListener)currentClass)
                        }
                        fields.set(currentClass,sourceView.findViewById(viewId))

                }catch(Exception e)
                {
                    e.printStachTrace();
                }
        }   
    }
}

这是一个静态的方法可以随时调用
可以在你的BaseActivity中进行是用直接传入activity对象

其实安卓中的注释式绑定控件(也是所谓的IOC控制反转在安卓中的一种应用)其实本质的使用就是java基础中反射的使用值得一提的是,反射执行的效率是很低的。
如果不是必要,应当尽量减少反射的使用,因为它会大大的拖累你应用的执行效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值