android 进阶之注解框架搭建


今天重点内容是android懒人式开发(注解)框架的搭建。废话不多说,请看图:

这里写图片描述

@contentView这个注解呢就是延伸在类之上的,只有类才能使用这个标签,表示引用那个activity的xml。
@findViewById这个注解呢是用在类里面的字段上,表示通过这个id找到这个控件并赋值给用于这个标签的控件上。


下面来看代码:首先我们先看2个注解类,contentView这个注解类主要是作用于类,而findViewById这个注解类主要是作用于字段。并且这2个类都可以通过JVM或其他使用反射机制的代码所读取和使用。

package com.wyw.annotationdemo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//ElementType.TYPE表示着这个注解作用于类、接口或枚举;
//ElementType.FIELD表示着这个注解作用于字段;
//ElementType.METHOD表示着这个注解作用于方法;
//ElementType.PARAMETER表示着这个注解作用于参数;
//ElementType.CONSTRUCTOR表示着这个注解作用于构造函数;
//ElementType.LOCAL_VARIABLE表示着这个注解作用于局部变量;
//ElementType.ANNOTATION_TYPE表示着这个注解作用于注释类型;
//ElementType.PACKAGE  表示着这个注解作用于包;

//RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略
//RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略
//RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface contentView {
    int value();//布局id
}
-------------------------------------------

package com.wyw.annotationdemo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface findViewById {
    int value();//控件id
}

注解类已经写完,现在该是看调用注解的并反射activity方法的类了:

initContentView这个方法呢是初始化activity的xml。通过class拿到类的注解,并且直接反射该类的setContentView,并把注解的id传进去。

initView这个方法是把控件findViewById出来,首先我们先拿到类里面的所有属性(字段),并且通过这个属性拿到这个属性的注解,通过反射该类的findViewById方法,并且把注解的id传进去。通过反射拿到id的控件,并且把这个控件设置给这个属性(字段)。

package com.wyw.annotationdemo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.app.Activity;

public class AnnotateUtils {
    /** 通过类注解来设置布局 */
    public static void initContentView(Activity activity) {
        Class<? extends Activity> clazz = activity.getClass();
        // 拿到类的注解(因为是类注解所以要直接用类来拿)
        contentView cView = clazz.getAnnotation(contentView.class);
        if (cView != null) {
            try {
                // 拿到指定方法
                Method method = clazz.getMethod("setContentView", int.class);
                // 拿到findViewById这个方法返回回来的view
                method.invoke(activity, cView.value());
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
    }

    /** 通过注解设置控件值 */
    public static void initView(Activity activity) {
        Class<? extends Activity> clazz = activity.getClass();
        // 获得类的所有属性。
        Field[] fields = clazz.getDeclaredFields();
        // 遍历所有成员变量
        for (Field field : fields) {
            // 拿到属性注解(因为是类里面的属性注解,所以要再类里面的属性里面拿)
            findViewById viewById = field.getAnnotation(findViewById.class);
            if (viewById != null) {
                int viewId = viewById.value();
                if (viewId != -1) {
                    try {
                        // 初始化View
                        Method method = clazz.getMethod("findViewById",int.class);
                        // 拿到findViewById这个方法返回回来的view
                        Object resView = method.invoke(activity, viewId);
                        field.setAccessible(true);
                        // 设置注解下面的属性的值 = resView;
                        field.set(activity, resView);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

注解和反射都写完了,接下来该写个基类来调用这个反射了,代码如下:AnnotateUtils.initContentView(this);调用activity的xml。AnnotateUtils.initView(this);初始化控件

package com.wyw.annotationdemo;

import android.app.Activity;
import android.os.Bundle;

public abstract class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AnnotateUtils.initContentView(this);
        AnnotateUtils.initView(this);
        init();
    }

    /** 初始化 */
    protected abstract void init();

}

本篇博客就到这里,如果有有疑问的欢迎留言讨论。同时希望大家多多关注我的博客,多多支持我。

尊重原创转载请注明:(http://blog.youkuaiyun.com/u013895206) !

下面是地址传送门:址:http://download.youkuaiyun.com/detail/u013895206/9482743

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值