本文整理一下WMRouter
的基本路由逻辑,并剖析相关路由类的设计。
先来简单理解一下WMRouter
路由过程中的几个基本元素 :
UriRequest
: 用于封装一个路由请求
UriInterceptor
: 代表一个拦截器,可以对一个UriRequest
进行拦截,通过UriCallback
来告诉拦截结果。
UriCallback
: Uri处理的一个统一回调。 回调它的onNext
方法代表继续处理、回调它的onComplete
代表这次路由请求处理完毕。
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);
//子类需要重写的处理逻辑
protected abstract void handleInternal(@NonNull UriRequest request, @NonNull UriCallback callback);
}
UriHandler
在对一个Uri
处理时,会调用handle
方法,这个方法定义了一个UriRequest
被处理的基本过程。
//处理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
被处理的基本逻辑可用用下图表示 :
所以,定义一个基本的处理Uri
的类应继承自UriHandler
,并复写handleInternal
方法。
上面源码你会发现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
方法。
概念和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
中路由的基本组成元素UriRequest
、UriHandler
、UriInterceptor
、ChainedHandler
、ChainedInterceptor
。那WMRouter
是如何使用这些基本元素来搭建一个路由框架的呢 ?
它继承自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
中路由的起点UriHandler
为DefaultRootUriHandler
,它继承自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
拦截。那么这次路由请求就结束了。
所以整个路由框架大体路由架构如下图所示 :
下一节我们会看一下 PageAnnotationHandler
、UriAnnotationHandler
是如何生成的 : 路由节点的动态生成
欢迎Star我的Android进阶计划,看更多干货。