基于arouter模块间通信的简单封装--使便于使用

基于arouter模块间通信的简单封装--使便于使用

想要查看具体demo请点击这里

在组件化开发的过程中我们我和在业务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;
        }
    }

}

待实现的问题:方法的异步回调。

原创文章 63 获赞 59 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u013049016/article/details/99456656