All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hadoopz.MyDroidLib.inject.ViewInjectorImpl Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2018 jw362j.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hadoopz.MyDroidLib.inject;
import java.util.HashSet;
import android.app.Activity;
import android.view.View;
import java.lang.reflect.Method;
import android.view.LayoutInflater;
import com.hadoopz.MyDroidLib.inject.annotation.ContentView;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import android.view.ViewGroup;
import com.hadoopz.MyDroidLib.inject.annotation.Event;
import com.hadoopz.MyDroidLib.inject.annotation.ViewInject;
import com.mycomm.IProtocol.log.UniversalLogHolder;
import java.lang.reflect.InvocationTargetException;





/**
 *
 * @author jw362j
 */
public class ViewInjectorImpl implements ViewInjector{
    private static final String TAG = "ViewInjectorImpl";

    private static final HashSet> IGNORED = new HashSet>();

    static {
        IGNORED.add(Object.class);
        IGNORED.add(Activity.class);
        IGNORED.add(android.app.Fragment.class);
        try {
            IGNORED.add(Class.forName("android.support.v4.app.Fragment"));
            IGNORED.add(Class.forName("android.support.v4.app.FragmentActivity"));
        } catch (Throwable ignored) {
        }
    }

    private static final Object lock = new Object();
    private static volatile ViewInjectorImpl instance;

    private ViewInjectorImpl() {
    }

    public static void registerInstance() {
        if (instance == null) {
            synchronized (lock) {
                if (instance == null) {
                    instance = new ViewInjectorImpl();
                }
            }
        }
        y.setViewInjector(instance);
    }

    @Override
    public void inject(View view) {
        injectObject(view, view.getClass(), new ViewFinder(view));
    }

    @Override
    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 (NoSuchMethodException ex) {
            UniversalLogHolder.e(TAG, ex.getMessage());
        } catch (SecurityException ex) {
            UniversalLogHolder.e(TAG, ex.getMessage());
        } catch (IllegalAccessException ex) {
            UniversalLogHolder.e(TAG, ex.getMessage());
        } catch (IllegalArgumentException ex) {
            UniversalLogHolder.e(TAG, ex.getMessage());
        } catch (InvocationTargetException ex) {
            UniversalLogHolder.e(TAG, ex.getMessage());
        }

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

    @Override
    public void inject(Object handler, View view) {
        injectObject(handler, handler.getClass(), new ViewFinder(view));
    }

    @Override
    public View inject(Object fragment, LayoutInflater inflater, ViewGroup container) {
        // inject ContentView
        View view = null;
        Class handlerType = fragment.getClass();
        try {
            ContentView contentView = findContentView(handlerType);
            if (contentView != null) {
                int viewId = contentView.value();
                if (viewId > 0) {
                    view = inflater.inflate(viewId, container, false);
                }
            }
        } catch (Throwable ex) {
            UniversalLogHolder.e(TAG, ex.getMessage());
        }

        // inject res & event
        injectObject(fragment, handlerType, new ViewFinder(view));

        return view;
    }

    /**
     * 从父类获取注解View
     */
    private static ContentView findContentView(Class thisCls) {
        if (thisCls == null || IGNORED.contains(thisCls)) {
            return null;
        }
        ContentView contentView = thisCls.getAnnotation(ContentView.class);
        if (contentView == null) {
            return findContentView(thisCls.getSuperclass());
        }
        return contentView;
    }

    @SuppressWarnings("ConstantConditions")
    private static void injectObject(Object handler, Class handlerType, ViewFinder finder) {
        y.log("in injectObject,handler:"+handler+",handlerType:"+handlerType+",finder:"+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 (IllegalAccessException ex) {
                        UniversalLogHolder.e(TAG, ex.getMessage());
                    } catch (RuntimeException ex) {
                        UniversalLogHolder.e(TAG, ex.getMessage());
                    }
                }
            }
        } // end inject view

        // inject event
        Method[] methods = handlerType.getDeclaredMethods();
        y.log("in injectObject,methods:"+methods);
        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) {
                    y.log("in injectObject,method is Annotation by Event");
                    try {
                        // id参数
                        int[] values = event.value();
                        int[] parentIds = event.parentId();
                        int parentIdsLen = parentIds == null ? 0 : parentIds.length;
                        y.log("in injectObject,values:"+values+",method:"+method);
                        //循环所有id,生成ViewInfo并添加代理反射
                       if(values != null){
                            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) {
                        UniversalLogHolder.e(TAG,ex.getMessage());
                    }
                }
            }
        } else{
           y.log("in injectObject,methods is null"); 
        }

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy