基于反射制作Ioc库(上)

  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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值