在開發組件化項目中,遇到一個這樣的問題,兩個不同的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