为了账号安全,请及时绑定邮箱和手机立即绑定

WMRouter源码分析(1)-基本结构分析

标签:
Android

本文整理一下WMRouter的基本路由逻辑,并剖析相关路由类的设计。

基本元素

先来简单理解一下WMRouter路由过程中的几个基本构成元素 :

UriRequest : 封装了一个路由请求

UriInterceptor : 代表一个拦截器,可以对一个UriRequest进行拦截,通过UriCallback来告诉拦截结果。

UriCallback : Uri处理的一个统一回调。 回调它的onNext方法代表继续处理、回调它的onComplete代表这次路由请求处理完毕。

UriHandler (定义基本的路由逻辑)

WMRouter中,对于每一个或每一类Uri都会有一个UriHandler来处理,UriHandler定义了处理一个Uri的基本逻辑。

public abstract class UriHandler {    //拦截器列表
    protected ChainedInterceptor mInterceptor;    //添加拦截器
    public UriHandler addInterceptor(@NonNull UriInterceptor interceptor) {
        ....
    }    //Uri处理的基本流程, 
    public void handle(@NonNull final UriRequest request, @NonNull final UriCallback callback) {
        ...
    }    // 是否要处理给定的URI
    protected abstract boolean shouldHandle(@NonNull UriRequest request);    //子UriHandler需要写的处理逻辑
    protected abstract void handleInternal(@NonNull UriRequest request, @NonNull UriCallback callback);
}

UriHandler在对一个Uri处理时,会调用handle方法,因此我们可以通过这个方法理清一个Uri被路由的基本处理过程

    //处理URI。通常不需要覆写本方法。
    public void handle(@NonNull final UriRequest request, @NonNull final UriCallback callback) {        if (shouldHandle(request)) { //是否可以处理这个 uri  request
            if (mInterceptor != null && !request.isSkipInterceptors()) {
                mInterceptor.intercept(request, new UriCallback() { 
                    @Override public void onNext() {
                        handleInternal(request, callback);
                    }                    @Override public void onComplete(int result) {
                        callback.onComplete(result);
                    }
                });
            } else {
                handleInternal(request, callback);
            }
        } else {
            callback.onNext();
        }
    }

OK,在WMRouter中一个uri被处理的基本逻辑可用用下图表示 :

webp

UriHandle.handle().png

所以,定义一个基本的处理Uri的类应继承自UriHandler,并复写handle方法。

ChainedInterceptor

上面源码你会发现UriHandler中的拦截器类型是ChainedInterceptor,并不是UriInterceptor。那 ChainedInterceptor 是一个什么样的拦截器呢 ?:

public class ChainedInterceptor implements UriInterceptor{    private final List<UriInterceptor> mInterceptors = new LinkedList<>();
}

即也是一个拦截器, 不过它含有一个拦截器列表。那么这个拦截器是如何工作的呢?看一下它的intercept()方法 :

    public void intercept(@NonNull UriRequest request, @NonNull UriCallback callback) {
        next(mInterceptors.iterator(), request, callback);    
    }    private void next(@NonNull final Iterator<UriInterceptor> iterator, @NonNull final UriRequest request, @NonNull final UriCallback callback) {        if (iterator.hasNext()) {  //对于链上的每一个 interceptor 都要调用一遍它的 intercept 方法
            iterator.next().intercept(request, new UriCallback() {                @Override public void onNext() {
                    next(iterator, request, callback);
                }                @Override public void onComplete(int resultCode) {
                    callback.onComplete(resultCode);
                }
            });
        } else {
            callback.onNext();
        }
    }

即,依次遍历每一个UriInterceptor,调用其intercept方法。

ChainedHandler

概念和ChainedInterceptor类似,它其实也是一个UriHandler, 也含有一个UriHandler列表,在其handleInternal方法中,会依次调用UriHandler.handle()

    @Override
    protected void handleInternal(@NonNull final UriRequest request, @NonNull final UriCallback callback) {
        next(mHandlers.iterator(), request, callback);
    }    private void next(@NonNull final Iterator<UriHandler> iterator, @NonNull final UriRequest request,
                      @NonNull final UriCallback callback) {        if (iterator.hasNext()) {
            UriHandler t = iterator.next();
            t.handle(request, new UriCallback() {                @Override
                public void onNext() {
                    next(iterator, request, callback);
                }                @Override
                public void onComplete(int resultCode) {
                    callback.onComplete(resultCode);
                }
            });
        } else {
            callback.onNext();
        }
    }

上面我们了解了WMRouter中路由的基本组成元素UriRequestUriHandlerUriInterceptorChainedHandlerChainedInterceptor。那WMRouter是如何使用这些基本元素来搭建一个路由框架的呢 ?

RootUriHandler (路由的起点)

它继承自ChainedHandler,提供startUri(UriRequest)并传入RootUriCallback来作为一次路由的起点:

    public void startUri(@NonNull UriRequest request) {
        ...
        handle(request, new RootUriCallback(request));
    }    protected class RootUriCallback implements UriCallback {        private final UriRequest mRequest;
        ... 

        @Override public void onNext() {
            onComplete(CODE_NOT_FOUND);
        }        
        @Override public void onComplete(int resultCode) {            switch (resultCode) {                case CODE_REDIRECT:   // 重定向,重新跳转
                    startUri(mRequest);                    break;                case CODE_SUCCESS:
                    mRequest.putField(UriRequest.FIELD_RESULT_CODE, resultCode);
                    onSuccess(mRequest); //全局路由成功回调
                    break;                default:
                    mRequest.putField(UriRequest.FIELD_RESULT_CODE, resultCode);
                    onError(mRequest, resultCode); //全局路由失败回调
                    break;
            }
        }
    }

WMRouter中路由的起点UriHandlerDefaultRootUriHandler,它继承自RootUriHandler, 这个UriHandler在起始时添加了下面4个子UriHandler :

    public DefaultRootUriHandler(Context context,@Nullable String defaultScheme, @Nullable String defaultHost) {

        addChildHandler(createPageAnnotationHandler(), 300);    // 处理@RouterPage注解定义的内部页面跳转
      
        addChildHandler(createUriAnnotationHandler(defaultScheme, defaultHost), 200);   //处理@RouterUri注解定义的URI跳转,
       
        addChildHandler(createRegexAnnotationHandler(), 100); //处理@RouterRegex注解定义的uri

        addChildHandler(new StartUriHandler(), -100); //支持Android原生隐士跳转
    }

这几个子UriHandler当然也是继承自UriHandler, 这里每一个子UriHandler都是一个ChainedHandler,即都会含有很多UriHandler

那如何开始一次路由呢? 即使用 DefaultRootUriHandler.startUri(UriRequest)DefaultRootUriHandler就会把这个UriRequest依次分发给其子UriHandler
一旦有一个UriHandler处理或者这个UriInterceptor拦截。那么这次路由请求就结束了。

所以整个路由框架大体路由架构如下图所示 :

webp

WMRouter路由体系.png

下一节我们会看一下 PageAnnotationHandlerUriAnnotationHandler是如何生成的 : 路由节点的动态生成



作者:susion哒哒
链接:https://www.jianshu.com/p/24f9af0209ce


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消