Xutils3源码阅读,体验高大上的注解

       Xutils3如何导入到项目这里就不做介绍了,网上很多教程,我们这里只是阅读源码了。

             首先来看下基本的使用方法吧,根据github上面的我们都是这样进行Xutils的初始化了


x.view().inject(this);

在使用Xutils对View进行注入的时候,其实是通过反射拿到传入的this(当前Activiy),再通过反射拿到我们平时所使用的setContextView()方法,拿到对应的函数之后调用invoke(),去执行当前方法,绕了一圈其实最后调用的还是setContentView();

public void inject(Activity activity) {
    //获取Activity的ContentView的注解
    Class<?> handlerType = activity.getClass();
    try {
        ContentView contentView = findContentView(handlerType);
        if (contentView != null) {
            int viewId = contentView.value();
            if (viewId > 0) {
                Method setContentViewMethod = handlerType.getMethod("setContentView", int.class);
                setContentViewMethod.invoke(activity, viewId);
            }
        }
    } catch (Throwable ex) {
        LogUtil.e(ex.getMessage(), ex);
    }

    injectObject(activity, handlerType, new ViewFinder(activity));
}

这一段代码主要是通过反射去获得所有的属性
ViewInject viewInject = field.getAnnotation(ViewInject.class);
if (viewInject != null) {
    try {
        View view = finder.findViewById(viewInject.value(), viewInject.parentId());
        if (view != null) {
            field.setAccessible(true);
            field.set(handler, view);
        } else {
            throw new RuntimeException("Invalid @ViewInject for "
                    + handlerType.getSimpleName() + "." + field.getName());
        }
    } catch (Throwable ex) {
        LogUtil.e(ex.getMessage(), ex);
    }
}

这才是上面的注释所标明的地方啊,ViewInject,通过拿到ViewInject这个注解,再通过viewInject.value()去拿到对应的资源文件的int值,再通过findViewById去查找View,到这里我们平时所使用的多么高大上的框架,最终也是调用了我们平时所写的那么几个简单的代码。
属性注入:利用反射去获取Annotation,然后获得对应的value(资源文件int值),调用findViewById(),再通过反射去注入属性
事件注入:利用反射去获取Annotation,然后获得对应的value(资源文件int值),调用findViewById(),再通过反射拿到View.OnClickListener,拼接一个set,反射去调用SetOnClickListener(),再通过动态代理反射执行方法。

// inject event
Method[] methods = handlerType.getDeclaredMethods();
if (methods != null && methods.length > 0) {
    for (Method method : methods) {

        if (Modifier.isStatic(method.getModifiers())
                || !Modifier.isPrivate(method.getModifiers())) {
            continue;
        }

        //检查当前方法是否是event注解的方法
        Event event = method.getAnnotation(Event.class);
        if (event != null) {
            try {
                // id参数
                int[] values = event.value();
                int[] parentIds = event.parentId();
                int parentIdsLen = parentIds == null ? 0 : parentIds.length;
                //循环所有id,生成ViewInfo并添加代理反射
                for (int i = 0; i < values.length; i++) {
                    int value = values[i];
                    if (value > 0) {
                        ViewInfo info = new ViewInfo();
                        info.value = value;
                        info.parentId = parentIdsLen > i ? parentIds[i] : 0;
                        method.setAccessible(true);
                        EventListenerManager.addEventMethod(finder, info, event, handler, method);
                    }
                }
            } catch (Throwable ex) {
                LogUtil.e(ex.getMessage(), ex);
            }
        }
    }
} // end inject event

猜你喜欢

转载自blog.csdn.net/guim_007/article/details/73610278
今日推荐