android 进阶之注解框架搭建

来源:互联网 发布:怎么申请淘宝网店 编辑:程序博客网 时间:2024/06/05 18:04

今天重点内容是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.csdn.net/u013895206) !

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

0 0
原创粉丝点击