UriRequest中包含Context、URI和Fields,其中Fields为HashMap,可以通过Key存放任意数据。简单起见,UriRequest类同时承担了Response的功能,跳转请求的结果,也会被保存到Fields中。
    存放到Fields中的常见字段举例如下,也可以根据需要自定义,为了避免冲突,建议字段名用完整的包名开头

    • Intent的Extra参数,Bundle类型
    • 用于startActivityForResult的RequestCode,int类型
    • 用于overridePendingTransition方法的页面切换动画资源,int[]类型
    • 本次跳转结果的监听器,OnCompleteListener类型

    每次URI跳转请求会有一个ResultCode(类似HTTP请求的ResponseCode),表示跳转结果,也存放在Fields中。常见Code如下,用户也可以自定义Code,为了避免冲突,自定义Code应使用负数值

    • 200:跳转成功
    • 301:重定向到其他URI,会再次跳转
    • 400:请求错误,通常是Context或URI为空
    • 403:禁止跳转,例如跳转白名单以外的HTTP链接、Activity的exported为false等
    • 404:找不到目标(Activity或UriHandler)
    • 500:发生错误

    UriHandler用于处理URI跳转请求,可以嵌套从而逐层分发和处理请求。UriHandler是异步结构,接收到UriRequest后处理(例如跳转Activity等),如果处理完成,则调用并传入ResultCode;如果没有处理,则调用callback.onNext()继续分发。

    下面的示例代码展示了一个只处理HTTP链接的UriHandler的实现。

    UriInterceptor为拦截器,不做最终的URI跳转操作,但可以在最终的跳转前进行各种同步/异步操作,常见操作举例如下:

    • URI跳转拦截,禁止特定的URI跳转,直接返回403(例如禁止跳转非meituan域名的HTTP链接)
    • URI参数修改(例如在HTTP链接末尾添加query参数)
    • 各种中间处理(例如打开登录页登录、获取定位、发网络请求)
    • ……

    举例来说,跳转某些页面需要先登录,可以实现一个LoginInterceptor如下。

    1. @Override
    2. public void intercept(@NonNull UriRequest request, @NonNull final UriCallback callback) {
    3. final FakeAccountService accountService = FakeAccountService.getInstance();
    4. if (accountService.isLogin()) {
    5. // 已经登录,不需处理,继续跳转流程
    6. } else {
    7. // 没登录,提示登录并启动登录页
    8. Toast.makeText(request.getContext(), "请先登录~", Toast.LENGTH_SHORT).show();
    9. accountService.registerObserver(new FakeAccountService.Observer() {
    10. @Override
    11. public void onLoginSuccess() {
    12. accountService.unregisterObserver(this);
    13. // 登录成功,继续跳转
    14. callback.onNext();
    15. }
    16. public void onLoginFailure() {
    17. accountService.unregisterObserver(this);
    18. // 登录失败,终止流程,返回错误ResultCode
    19. callback.onComplete(CustomUriResult.CODE_LOGIN_FAILURE);
    20. }
    21. });
    22. // 启动登录页
    23. startActivity(request.getContext(), LoginActivity.class);
    24. }
    25. }

    由于WMRouter是一个开放式组件化框架,UriRequest可以存放任意数据,UriHandler、UriInterceptor可以完全自定义,不同的UriHandler可以任意组合,具有很大的灵活性。但过于灵活容易导致易用性的下降,即使对于最常规最简单的应用,也需要复杂的配置才能完成功能。

    为了在两者之间平衡,WMRouter对包结构进行了划分,核心接口和实现类提供基础通用能力,尽可能保留最大的灵活性。可以在core包基础上进行自定义开发和配置,独立运行。

    • core:提供核心接口和实现类,提供基础通用能力。
    • utils:通用工具类。
    • components:辅助功能组件。
    • activity:Activity跳转相关。
    • regex:正则匹配相关。
    • common:UriHandler、UriInterceptor、UriRequest通用实现类。

    WMRouter还提供了ServiceLoader模块。

    • service:ServiceLoader模块。