文章是作者学习
WMRouter
的源码的重点纪要。 WMRouter官方文档 : https://mp.weixin.qq.com/s/pKRi5qpZmol7xFIfeBbK_A
本文整理一下WMRouter
的基本路由逻辑,并剖析相关路由类的设计。作者巧妙的使用继承设计了整个WMRouter
的路由体系,下面我们就从源码来看一下是如何实现的:
UriHandler
在WMRouter
中,对于每一个或每一类Uri
都会有一个UriHandler
来做处理,这个类定义了一个基本的处理逻辑。
该类处理Uri
的入口方法为handle
, 因此,理清它的主要处理逻辑,我们只需要看这个方法即可:
//处理URI。通常不需要覆写本方法。
public void handle(@NonNull final UriRequest request, @NonNull final UriCallback callback) {
if (shouldHandle(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();
}
}
mInterceptor
为 ChainedInterceptor
的实例,下面会介绍。
handle()
具体处理逻辑如下图:
UriInterceptor 与 ChainedInterceptor
UriInterceptor
为设置给UriHandler
的拦截器,在handleInternal
方法之前调用。
public interface UriInterceptor {
void intercept(@NonNull UriRequest request, @NonNull UriCallback callback);
}
UriHandler
中的拦截器是ChainedInterceptor
, ChainedInterceptor
实现了UriInterceptor
, 并含有一个UriInterceptor
列表,即支持添加多个拦截器,来看一下核心实现:
public void intercept(@NonNull UriRequest request, @NonNull UriCallback callback) {
next(mInterceptors.iterator(), request, callback); //对于链上的每一个 interceptor 都要调用一遍
}
private void next(@NonNull final Iterator<UriInterceptor> iterator, @NonNull final UriRequest request, @NonNull final UriCallback callback) {
if (iterator.hasNext()) {
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
方法。需要注意的是callback.onComplete(resultCode)
的调用,会导致路由的终止。
ChainedHandler
上面UriHandler
是处理一个uri的hanler,比如 A Activity的路由为test://a
,那么可以新建一个UriHandler
来处理,而ChainedHandler
则以列表组织多个UriHandler
,每向ChainedHandler
插入一个UriHandler
可以指定一个优先级,优先级高的会被插入到列表前面。ChainedHandler
复写了handleInternal
方法:
@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();
}
}
即ChainedHandler
会逐一调用每个UriHandler
的handle
方法。
上面我们了解了WMRouter
中路由的基本组成元素UriHandler
、UriInterceptor
、ChainedHandler
、ChainedInterceptor
, 接下来我们看下源码是如何使用它们构造路由体系的:
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;
public RootUriCallback(UriRequest request) {
mRequest = request;
}
@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
中路由的起点UriHandler
为DefaultRootUriHandler
,这个UriHandler
在起始时添加了下面4个子Handler:
public DefaultRootUriHandler(Context context,@Nullable String defaultScheme, @Nullable String defaultHost) {
// 处理RouterPage注解定义的内部页面跳转
addChildHandler(createPageAnnotationHandler(), 300);
// 处理RouterUri注解定义的URI跳转,如果注解没定义,继续分发到后面的Handler
addChildHandler(createUriAnnotationHandler(defaultScheme, defaultHost), 200);
// 处理RouterRegex注解定义的正则匹配
addChildHandler( createRegexAnnotationHandler(), 100);
addChildHandler(new StartUriHandler(), -100);
}
这几个子UriHandler
当然也是继承自UriHandler
, 对于每一个子Handler,下一节再分析。
经过上面的分析,我们大致可以总结WMRouter
的路由过程:
读后感
可以看到作者基本上使用两个概念UriHandler
和UriInterceptor
就完成了整个设计。并再此基础上引入了ChainedHandler
和ChainedInterceptor
,整体设计十分巧妙。
不过说实话,我在第一遍阅读这部分源码的时候ChainedHandler
与UriHandler
把我搅的是有点小头晕的。我想可能另一种设置思路如下:
网友评论