在开发组件化项目中,遇到一个这样的问题,两个不同的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

java(Android)跨Module调用对应类方法需求解决方案的更多相关文章

  1. AllJoyn+Android开发案例-android跨设备调用方法

    AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...

  2. Android 跨应用调用Activity

    http://blog.csdn.net/ouyangliping/article/details/7972141 如何调用另外一个app应用的activity或者service,本文提供一个验证可行 ...

  3. Android 跨应用调用Activity及Service

    如何调用另外一个app应用的activity或者service,本文提供一个验证可行的方法. 调用方法: Intent intent=new Intent("youActionName&qu ...

  4. Android 跨进程调用忽略权限

    Framework层: @Override    public StackInfo getStackInfo(int stackId) {        final int callingUid = ...

  5. JAVA如何跨项目调用接口

    public String load(String url, String query) throws Exception { URL restURL = new URL(url); /* * 此处的 ...

  6. Spring AOP调用本类方法为什么没有生效

    首先请思考一下以下代码执行的结果: LogAop.java //声明一个AOP拦截service包下的所有方法@Aspectpublic class LogAop { @Around("ex ...

  7. Android中的跨进程调用技术AIDL

    什么是AIDL Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信. 为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用 ...

  8. Golang、Php、Python、Java基于Thrift0.9.1实现跨语言调用

    目录: 一.什么是Thrift? 1) Thrift内部框架一瞥 2) 支持的数据传输格式.数据传输方式和服务模型 3) Thrift IDL 二.Thrift的官方网站在哪里? 三.在哪里下载?需要 ...

  9. Android四大组件应用系列5——使用AIDL实现跨进程调用Service

    一.问题描述 Android应用程序的四大组件中Activity.BroadcastReceiver.ContentProvider.Service都可以进行跨进程.在上一篇我们通过ContentPr ...

随机推荐

  1. Spring MVC 框架学习

    一.spirng的简介 Spring是一个开源框架,它由Rod Johnson创建.它是为了解决企业应用开发的复杂性而创建的.Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情. ...

  2. postgresql----SELECT

    示例1.简单查询 使用*查询表所有的字段,也可以指定字段名查询 test=# select * from tbl_insert; a | b ---+---- | sd | ff ( rows) te ...

  3. 170628、springboot编程之Druid数据源和监控配置一

    Spring Boot默认的数据源是:org.apache.tomcat.jdbc.pool.DataSource,那么如何修改数据源呢?我已目前使用比较多的阿里数据源Druid为例,如果使用其他的数 ...

  4. Yii 的session 实现返回上上页面

    学习session的页面:http://www.yiichina.com/doc/guide/2.0/runtime-sessions-cookies 关键摘要: $session = Yii::$a ...

  5. 商铺项目(Redis缓存)

    AOF,RDB是两种 redis持久化的机制.用于crash后,redis的恢复. 两种区别就是,AOF是持续的用日志记录写操作,crash后利用日志恢复:RDB是平时写操作的时候不触发写,只有手动提 ...

  6. Replication--复制与CDC和镜像

    复制和CDC 都是使用logreader来从日志中读取数据的变更,然后写入到分发库(复制)或变更表中. 1> 单独创建复制发布 在该情况下,会在分发服务器上创建日志读取代理作业(ServerNa ...

  7. Cardano(ADA), EOS, RChain(RHOC), Aeternity(AE) 都是极其好的币

    从区块链的基础知识出发,研究ETH和EOS的区别 免责声明:EOS目前还在开发中,我们对此项目的一些理解可能会改变.而且,我并不是以太坊开发者,而只是一个喜欢区块链的爱好者.请牢记这两点,请把下面的内 ...

  8. visual studio多工程开发配置

    文章:带你玩转Visual Studio——带你多工程开发 带你玩转Visual Studio——带你理解微软的预编译头技术 通过上一篇文章带你玩转Visual Studio——带你多工程开发的讲解, ...

  9. Js中的filter()方法

    /* filter()方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组. filter()基本语法: arr.filter(callback[, thisArg]) filte ...

  10. WebService—规范介绍和几种实现WebService的框架介绍

    一.关于SOA(面向服务架构)思想   1.关于协议   2.SOA 的诞生 SOA(Service-Oriented Architecture)面向服务架构是一种思想,它将应用程序的不同功能单元通过 ...