Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 440|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-1 14:11:38 | 显示全部楼层 |阅读模式
    在开发组件化项目中,遇到一个这样的问题,两个不同的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 = 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 = 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 

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-1 13:09 , Processed in 0.068927 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表