Android Route 路由解析 - tenji/ks GitHub Wiki

Android Route 路由解析

随着项目的开发,业务不断壮大,业务模块越来越多,各个模块间相互引用,耦合越来越严重,同时有些项目可能还需要独立对外输出,所以模块解耦,组件化变得尤为紧迫。

一、泛化路由简介

泛化模块路由,支持在各种 SDK 产品中使用(源码拷贝更新 applicationId 即可,内部可自由增加订制化内容) (本项目基于 ModularizationArchitecture,在其基础上进行了精简):

  1. 去掉了同步异步调用 Router 只负责做好解耦和转发工作,剩余的线程切换、同步异步看业务需要,在分发到业务之后,由具体业务操作线程同步异步;
  2. 去掉了跨进程组件;
  3. 作为通用 SDK 内部嵌入的 Router 较少用到跨进程,如果需要在主进程分发处做进程切换 此模块只有 Jar 包,不用在 manifest 声明任何组件,直接使用即可,无任何依赖。
  4. 一切目标为了精简,适合 SDK 产品使用;
  5. 反射动态拼装组件,像乐高积木一样任意组合输出子模块;
  6. 模块测试、编译更加简单高效。

二、路由方案演进

2.1 阶段一(原始社会)

如上图所示,早期代码没有任何细分,所有代码都在一个模块,模块直接直接依赖。

2.2 阶段二(奴隶社会)

伴随着模块业务功能的分工,不同的模块被拆分开来,但是随着业务直接互相调用,逐渐发展为如下阶段。

2.3 阶段三(封建社会)

各个模块直接依赖错综复杂,扩展和维护性大打折扣,于是爆发了现代革命。

2.4 阶段四(资本主义社会)

不同模块完全隔离,通过公共的 Router 模块进行通信,各个模块自由扩展,维护性大大提高。

模块可以动态拆解,按需打包使用,如下图:

更进化一步,将公共库抽离到 Router,模块复用度进一步提高。

后续多进程方案暂时不在本文讨论之列,因为可以在自己的模块完成多进程,不一定非要用 Router 操作多进程,减少 Router 的责任。

一次 Router 的调用时序如下:

三、使用方式

  • App:可运行的 APP Module;
  • Library Moudule:模块化中的单一业务或功能组件;
  • Action:跨模块调用的具体实现;
  • ActionResult:Action 调用后返回的结果;
  • Provider:Action 簇,将一组 Action 放到一起,便于注册;
  • RouterRequest:调用 Action 时的请求信息;
  • RouterResponse:Action 调用完成之后的响应信息;
  • LocalRouter:单进程本地局域路由器

3.1 在 Application oncreate 中初始化 Router

// 注册 Router
RouterManager.getInstance().registerApplicationLogic(MainApplicationLogic.class);
RouterManager.getInstance().registerApplicationLogic(WebApplicationLogic.class);
RouterManager.getInstance().registerApplicationLogic(MusicApplicationLogic.class);
RouterManager.getInstance().registerApplicationLogic(PicApplicationLogic.class);
// 初始化 Router
RouterManager.getInstance().init(this);

3.2 创建自定义 ApplicationLogic

public class CustomApplicationLogic extends BaseApplicationLogic {
    @Override
    public void onCreate() {
        // 注册 Provider,详见 2.4
        LocalRouter.getInstance(mApplication).registerProvider("util", new UtilProvider());
    }
}

3.3 创建 Provider

public class UtilProvider extends MaProvider {
    @Override
    protected void registerActions() {
        registerAction("md5",new MD5EncryptAction());
    }
}

3.4 实现 Action

public class PlayAction implements RouterAction {

    @Override
    public void invoke(Context context, HashMap requestData, RouterCallback callback) {
        Intent intent = new Intent(context, MusicService.class);
        intent.putExtra("command", "play");
        context.startService(intent);
        if (callback != null) {
            HashMap result = new HashMap();
            result.put(RouterCallback.KEY_VALUE,"play success");
            callback.onResult(RouterCallback.CODE_SUCCESS,result);
        }
    }

}

3.5 调用

RouterManager.getInstance().route(context, routerRequestBuilder);

参考链接