• java(Android)跨Module调用对应类方法需求解决方案


    在开发组件化项目中,遇到一个这样的问题,两个不同的Module相互之间没有任何直接依赖关系,现在需求是需要在Module_A中调用Module_B中的某个类的方法,以下为解决此问题的方法;
    
    采用的核心技术:路由、反射;
    
    解决问题的过程,首先将需要调用的类通过路由注册,注册到路由中心,这里讲Module_B中的类注册到了路由中心,在Module_A中首先先通过路由中心获取到已经注册了的Module_B的类,获取到Class后通过反射原理获取当前对象实例,然后继续通过反射调用调用当前实例对象的对应方法(支持无参方法及有参方法),至此调用方法已实现,具体示例如下:
    
    1、路由注册工具类:
    
    /**
     * Class类路由注册工具类
     * Created by sun.li on 2018/7/6.
     *
     * @author sun.li
     */
    
    public class RouterClassUtil implements RouterInter<Object,Class<? extends Object>>{
    
        private ConcurrentHashMap<String, Class<? extends Object>> mClassZ = new ConcurrentHashMap();
        private ConcurrentHashMap<String, Object> mClassA = new ConcurrentHashMap();
        private static RouterClassUtil mInstance;
    
        private RouterClassUtil() {
        }
    
        public static RouterClassUtil getInstance() {
            if(null == mInstance) {
                synchronized(RouterActivity.class) {
                    if(null == mInstance) {
                        mInstance = new RouterClassUtil();
                    }
                }
            }
            return mInstance;
        }
    
        @Override
        public void routerT(String key, Object obj) {
            Object cacheActivity = this.mClassA.get(key);
            if(null == cacheActivity || obj != cacheActivity) {
                this.mClassA.put(key, obj);
            }
        }
    
        @Override
        public Object invokT(String key) {
            return this.mClassA.get(key);
        }
    
        @Override
        public void routerV(String key, Class<?> aClass) {
            Class cacheClass = this.mClassZ.get(key);
            if(null == cacheClass || aClass != cacheClass) {
                this.mClassZ.put(key, aClass);
            }
        }
    
        @Override
        public Class<? extends Object> invokV(String key) {
            return this.mClassZ.get(key);
        }
    
        /** 获取Object对象*/
        public Object getObject(String key){
            Object object = invokT(key);
            if(null == object){
                try {
                    Class<? extends Object> aClass = invokV(RouterHttpClassKey.KEY_MODULE_HTTP_HTTPUTIL);
                    if(null != aClass) {
                        object = aClass.newInstance();//通过Class对象实例化当前对象
                    }
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            return object;
        }
    }
    
    2、路由对应Class配置类(此处声明具体的Class类路径,注册时通过反射原理获取对应的Class):
    
    /**
     * 路由跳转Class对应key配置类
     * Created by sun.li on 2018/7/6.
     *
     * @author sun.li
     */
    
    public class RouterHttpClassKey {
    
        /**
         * HttpUtil
         */
        public static final String KEY_MODULE_HTTP_HTTPUTIL = "**.**.**.util.HttpLibUtil";
    }
    
    3、路由注册:
    
    RouterClassUtil.getInstance().routerV(value,correspondingClass);
    
    4、路由调用获取当前的对象并且通过反射调用对应的方法:
    
    4.1、无参方法调用:
    
    /** 调用Module中的对应无参方法*/
    public void callMethodInModule(@NonNull String className,@NonNull String methodName){
        Object object = RouterClassUtil.getInstance().getObject(className);
        if (null != object) {
            Method method = getMethod(object,methodName,null);
            if(null!=method){
                try {
                    //执行对象object中通过反射获取的方法
                    method.invoke(object);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    4.2、有参方法调用(发射调用多参数时因为方法限制,还未想到好的方式):
    
    /**
     * 公共网络请求参数对象
     * Created by sun.li on 2018/7/6.
     *
     * @author sun.li
     */
    
    public class BaseObjectParameterBean {
    
        public BaseObjectParameterBean(){
    
        }
    
        public BaseObjectParameterBean(Class parameterType, Object parameterValue){
            setParameterType(parameterType);
            setParameterValue(parameterValue);
        }
    
        /** 参数值*/
        private Object parameterValue;
    
        /** 参数类型*/
        private Class parameterType;
    
        public Object getParameterValue() {
            return parameterValue;
        }
    
        public void setParameterValue(Object parameterValue) {
            this.parameterValue = parameterValue;
        }
    
        public Class getParameterType() {
            return parameterType;
        }
    
        public void setParameterType(Class parameterType) {
            this.parameterType = parameterType;
        }
    }
    
    /** 调用Module中的对应有参方法*/
    public void callMethodInModule(@NonNull String className, @NonNull String methodName, List<BaseObjectParameterBean> mList){
        if(null!=mList && mList.size()>0){
            /* 参数类型集合*/
            List<Class> classList = new ArrayList<>();
            /* 参数值集合*/
            List<Object> objectList = new ArrayList<>();
            for (int i = 0; i < mList.size(); i++) {
                BaseObjectParameterBean baseHttpRequestParameterBean = mList.get(i);
                if(null != baseHttpRequestParameterBean){
                    if(null != baseHttpRequestParameterBean.getParameterValue() && null != baseHttpRequestParameterBean.getParameterType()){
                        classList.add(baseHttpRequestParameterBean.getParameterType());
                        objectList.add(baseHttpRequestParameterBean.getParameterValue());
                    }
                }
            }
            if(classList.size()>0 && objectList.size()>0){
                Object object = RouterClassUtil.getInstance().getObject(className);
                if (null != object) {
                    Method method = getMethod(object,methodName,classList);
                    if(null!=method){
                        try {
                            //执行对象object中通过反射获取的方法
                            Object[] mObjectList = new Object[objectList.size()];
                            for (int i = 0; i < objectList.size(); i++) {
                                if(null != objectList.get(i)){
                                    mObjectList[i] = objectList.get(i);
                                }
                            }
                            method.invoke(object,mObjectList);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }else{
            callMethodInModule(className,methodName);
        }
    }
    
    private Method getMethod(Object object, @NonNull String methodName, List<Class> mList){
        if(null == object || TextUtils.isEmpty(methodName)){
            return null;
        }
        Method method = null;
        try {
    
            if(null != mList && mList.size()>0){
                // 父类对象调用子类有参数的方法(反射原理)
                Class[] mClassList = new Class[mList.size()];
                for (int i = 0; i < mList.size(); i++) {
                    if(null != mList.get(i)){
                        mClassList[i] = mList.get(i);
                    }
                }
                method = object.getClass().getMethod(methodName,mClassList);
            }else{
                method = object.getClass().getMethod(methodName);// 父类对象调用子类方法(反射原理)
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return method;
    }
    
    4.3、调用示例:
    
    BaseObjectUtil.getInstance().callMethodInModule(RouterHttpClassKey.KEY_MODULE_HTTP_HTTPUTIL,"test");
    
    List<BaseHttpRequestParameterBean> beans = new ArrayList<>();
    beans.add(new BaseHttpRequestParameterBean(String.class,"哈哈"));
    beans.add(new BaseHttpRequestParameterBean(Integer.class,88));
    
    BaseHttpRequestParameterBean baseHttpRequestParameterBean = new BaseHttpRequestParameterBean();
    baseHttpRequestParameterBean.setParameterType(Integer.class);
    beans.add(baseHttpRequestParameterBean);
    
    BaseObjectUtil.getInstance().callMethodInModule(RouterHttpClassKey.KEY_MODULE_HTTP_HTTPUTIL,"test2",beans);
    
    调用结果:
    
    07-06 16:07:29.862 10329-10329/cc.**.** E/HttpLibUtil:: 我是HttpLib中的test方法
    07-06 16:07:29.862 10329-10329/cc.**.** E/HttpLibUtil:: 我是HttpLib中的test2方法,str=哈哈 i=88 
  • 相关阅读:
    linux centos 安装配置rsync
    linux下mysql权限配置
    让nginx支持patchinfo,(支持codeigniter,thinkphp,ZF等框架)
    nginx、php-fpm安装mongodb及驱动扩展
    redis和redis php扩展安装
    sea.js 入门
    require.js 入门笔记
    怎么玩耍图标字体.
    利用 Gulp 处理前端工作流程
    LESS 学习记录(简单入门)
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/10304034.html
Copyright © 2020-2023  润新知