(源码阅读)自己动手打造一套属于自己想IOC注解框架

       阅读过Xutils3和butterKnife的源码之后,稍微比对了一下,俩个都写的非常nb~~

          Xutils3通过源码发现,主要是通过反射去 获得属性,函数进行注入。

          而butterKnife通过将一系列的参数拼接起来重新生成一个.java文件打包到apk里面。

         so,我们还是来通过反射的方式打造自己的IOC注解框架吧。

public static void inject(ViewFinder finder , Object object){

    injectFiled(finder , object);   //属性注入
    injectEvent(finder , object);   //函数注入

}

private static void injectFiled(ViewFinder finder, Object object) {
    //1:获取类里面的所有属性
    Class<?> clazz = object.getClass();
    //获取类里面的所有属性集合
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields){
        //拿到类里面的属性上面的Annotation
        ViewById viewById = field.getAnnotation(ViewById.class);
        //2:获取ViewById的里面的resId的值
        if (viewById != null ){
            //拿到Annotation里面的resId值
            int viewId = viewById.value();
            //3:findViewById找到里面的View
            View view = finder.findViewById(viewId);

            if (view != null) {
                //4:动态注入找到的View
                field.setAccessible(true);
                try {
                    field.set(object, view);
                } catch (IllegalAccessException e) {
                    Log.e("--->", "ViewUtils inject failure..");
                    e.printStackTrace();
                }
            }
        }

    }
跟Xutils3的做法类似,通过反射去拿到当前类,再获得所有属性,对所有属性进行遍历,判断是否带有Annotation,拿到带有Annotation的属性进行View的注入、到这里,我们就完成了属性的注入了,我们在使用的时候就只需要

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

这样就像Xutils一样完成了属性的注入了,使用的时候

tv.setText("嘿嘿");
也不会出现空指针了~~~下面我们来看下点击函数的注入吧。

private static void injectEvent(ViewFinder finder, Object object) {

    Class<?> clazz = object.getClass();

    Method[] methods = clazz.getDeclaredMethods();

    for (Method method : methods) {

        OnClick clickMethod = method.getAnnotation(OnClick.class);

        if (clickMethod != null){
            int[] viewIds = clickMethod.value();
            for (int viewId : viewIds) {
                View view = finder.findViewById(viewId);

                boolean isCheckNet = method.getAnnotation(CheckNet.class) != null;
                if (view != null) {
                    view.setOnClickListener(new DeclaredOnClickListener(method, object, isCheckNet));
                }
            }
        }
    }
}
这里的原理和属性注入也是一样的,拿到带有Annotation的View之后,通过view.setOnClickListener来设置点击事件,在点击事件里通过反射去执行我们平时的OnClickListener(),到这里有没有觉得我们所使用的注解框架就是这么简单呢。

猜你喜欢

转载自blog.csdn.net/guim_007/article/details/73613735