基于arouter模块间通信的简单封装--使便于使用
在组件化开发的过程中我们我和在业务module和业务module之间相互调用呢?这里我采用的是arouter,如果还不知道arouter是什么怎么用的,请自行搜索arouter的集成和是使用方法。这里我只对里面的通信做了简单的封装,以期能够达到方便的使用效果。
下面我们先从使用说起
封装库的使用
首先来看一下项目的目录结构
首先app依赖于两个业务module也就是modulea和moduleb,两个业务module都依赖于baselib库,现在baselib库中只有一个功能库依赖即我们今天的主角库communicationinterface。
使用时我们先在被调用的类中实现ICommunication接口,也就是moduleb中的Provide类
@Route(path = RouteConstant.moduleb_provide)
public class Provide implements ICommunication<CommunicationTestModel> {
private final String TAG = this.getClass().getName();
@Override
public Object iCommunication(ParamCommunicationModel<CommunicationTestModel> params) {
Log.e(TAG, params.getData().getName());
return ConmunicationHelper.invokeMethod(this, params.getData());
}
@Override
public void init(Context context) {
}
private Object communicationOne(CommunicationTestModel params) {
return "communicationOne方法被调用的返回值";
}
private Object communicationTwo(CommunicationTestModel params) {
return "communicationTwo方法被调用的返回值";
}
}
我们在modulea中mainact中调用
@Route(path = RouteConstant.modulea_mainact)
public class MainActivity extends FragmentActivity {
private TextView mCommunicationOne;
private TextView mCommunicationTwo;
private CommunicationService<String> mCommunicationService;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_activity_main);
initView();
initCommunication();
}
private void initView() {
mCommunicationOne = findViewById(R.id.communication_one);
mCommunicationTwo = findViewById(R.id.communication_two);
initListener();
}
private void initCommunication() {
mCommunicationService = new CommunicationService<>();
}
private void initListener() {
mCommunicationOne.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//调用muduleb 的communicationOne方法并展示返回值
ReturnCommunicationModel<String> result = mCommunicationService.communication(new CommunicationTestModel(RouteConstant.moduleb_provide, "张三", "communicationOne"));
mCommunicationOne.setText(result.getData());
}
});
mCommunicationTwo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//调用muduleb 的communicationTwo方法并展示返回值
ReturnCommunicationModel<String> result = mCommunicationService.communication(new CommunicationTestModel(RouteConstant.moduleb_provide, "张三", "communicationTwo"));
mCommunicationTwo.setText(result.getData());
}
});
}
}
ReturnCommunicationModel result = mCommunicationService.communication(new CommunicationTestModel(RouteConstant.moduleb_provide, “张三”, “communicationOne”));这行代码就是调用方法传参及获取返回值的地方
我们来看一下调用前和调用后的界面
可以发现调用成功了,通信功能实现了。
实现中的思路
1.要实现统一:规定入参和出参格式,方便统一管理路由列表方便追踪调用者和被调用者。
2.多方法调用:摒弃之前的调几个方法,接口里就需要有几个方法的方式,原来的方式不适合方法的修改,要想添加一个或修改一个方法,造成的后果就是要修改调用方和被调用方都需要修改(在本例的封装中,最终采用反射实现多方法的调用,参数和返回值是固定格式的,做到修改尽量)
communicationinterface目录结构
首先说一下各个文件的作用
CommunicationService:通信连接服务类(通信时统一创建此类)
ICommunication:基础通信接口(通信实现类统一实现此接口)
BaseCommunicationModel:通信基础Model类(参数model必须要继承此类,方便统一管理type)
ParamCommunicationModel:参数model类
ReturnCommunicationModel:返回model类
ConmunicationHelper:通信帮助类(用于一个被调用类有多个方法可能被调用时)
代码实现
我们知道要实现通信需要先实现IProvider接口
因此第一步我们定义一个通信基础接口(所有通信的以后都要实现这个接口)
//基础通信接口(通信实现类统一实现此接口)
public interface ICommunication<T> extends IProvider {
Object iCommunication(ParamCommunicationModel<T> params);
}
第二步我们定义请求参数和返回参数,使调用统一也便于管理路由地址
//请求参数 通信基础Model类(参数model必须要继承此类,方便统一管理type)
public class BaseCommunicationModel {
private String type;//类型或者路由地址
protected String methodName;//只有一个方法时不需要初始化(使用默认方法时不需要初始化)
public BaseCommunicationModel(String type) {
this.type = type;
}
public BaseCommunicationModel(String methodName, String type) {
this.methodName = methodName;
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
}
//返回model类
public class ReturnCommunicationModel<T> {
private Object data;
public T getData() {
return (T) data;
}
public void setData(Object data) {
this.data = data;
}
}
第三部解决到方法调用的问题,使用反射调用,代码如下:
//通信帮助类(用于一个被调用类有多个方法可能被调用时)
public class ConmunicationHelper {
/**
* @param context 要反射的对象实例
* @param params 通信参数
* @param <T>
*/
public static <T extends BaseCommunicationModel> Object invokeMethod(Object context, T params) {
try {
Class cla = context.getClass();
Method declaredMethod = cla.getDeclaredMethod(params.getMethodName(), params.getClass());
declaredMethod.setAccessible(true);
return declaredMethod.invoke(context, params);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
待实现的问题:方法的异步回调。