关闭

基于反射制作Ioc库(上)

标签: 反射-Ioc-And
358人阅读 评论(0) 收藏 举报
分类:
  1. 介绍
    在Android项目中,初始化View是必不可少的一部分,
    public final View findViewById (int id)或者Activity中的 public View findViewById (int id)需要我们手动的转换View类型,基于泛型对其简单封装
@SuppressWarnings("unchecked")
public static <T> T findViewById(Activity activity, int viewId) {
        return (T) activity.findViewById(viewId);
    }

@SuppressWarnings("unchecked")
public static <T> T findViewById(View viewParent, int viewId) {
        return (T) viewParent.findViewById(viewId);
}

但是在对View做单击、双击事件时仍然比较繁琐,下面我们开始基于反射制作我们自己的Ioc框架,Xutils、Andbase等原理类似。依赖注入具体到可以有构造注入、set函数注入、注解标注等,比较常用的就是基于注解标注的方式,在几个比较著名的依赖注入库中个人比较喜欢android annotations的注解名称,这里只以@ViewById 和 @Click为例

2. 注解定义和使用实例

@Retention(RetentionPolicy.RUNTIME) 表示注解保留到运行期
@Target(value = ElementType.FIELD) 表示注解只能标注在属性上
public @interface ViewById {
    int value() default 0;
}

@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.METHOD)
public @interface Click {
        int value() default 0;
}

使用实例

@ViewById(R.id.tv)
TextView tv;

@Click(R.id.tv)
public void onTvClicked() {
    toast("ioc onClick");
}

@Click(R.id.tv)
public void onTvClicked(TextView tv) {
    tv.setText("ioc onClick");
}

3.核心方法的编写

@ViewById(R.id.tv)
TextView tv;

上面在使用中仅仅对tv属性标注了注解,我们还需要在Activity运行时动态注入。

获取该Activity所有的属性信息

Class<? extends ActivityBase> clazz = getClass();
Field[] declaredFields = clazz.getDeclaredFields();

遍历其属性列表,找出标注了我们预定义的ViewById注解

for (Field field : declaredFields) {
            if (field.isAnnotationPresent(ViewById.class)) {
                ViewById annotationViewById = field.getAnnotation(ViewById.class);
                if (annotationViewById != null) {
                    ..............
                }
            }
}

通过注解获得Id信息,并把获取的View赋值给该属性

for (Field field : declaredFields) {
            if (field.isAnnotationPresent(ViewById.class)) {
                ViewById annotationViewById = field.getAnnotation(ViewById.class);
                if (annotationViewById != null) {
                    int viewId = annotationViewById.value();
                    field.setAccessible(true);
                    try {
                        field.set(this, findViewById(viewId));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    }
                }
            }
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:18816次
    • 积分:396
    • 等级:
    • 排名:千里之外
    • 原创:20篇
    • 转载:0篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论