XUtil注釋方式解析流程

Paste_Image.png

BaseActivity進行初始化

Paste_Image.png

繼承的Activity綁定ContentView

Paste_Image.png

內部執行過程

Paste_Image.png

遞歸查找是否注解了ContentView

Paste_Image.png

查找是否注解了field和method排除一些類型

private static void injectObject(Object handler, Class<?> handlerType, ViewFinder finder) {

    if (handlerType == null || IGNORED.contains(handlerType)) {
        return;
    }

    // 從父類到子類遞歸
    injectObject(handler, handlerType.getSuperclass(), finder);

    // inject view
    Field[] fields = handlerType.getDeclaredFields();
    if (fields != null && fields.length > 0) {
        for (Field field : fields) {

            Class<?> fieldType = field.getType();
            if (
            /* 不注入靜態字段 */     Modifier.isStatic(field.getModifiers()) ||
            /* 不注入final字段 */    Modifier.isFinal(field.getModifiers()) ||
            /* 不注入基本類型字段 */  fieldType.isPrimitive() ||
            /* 不注入數組類型字段 */  fieldType.isArray()) {
                continue;
            }

            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);
                }
            }
        }
    } // end inject view

    // 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

}

不過效率上用反射的方式可能有問題

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容