我们以一个最简单的使用场景来分析。
三部曲
1. 首先在Appliction中初始化
class App : Application() {
override fun onCreate() {
super.onCreate()
val rootUriHandler = DefaultRootUriHandler(this)
Router.init(rootUriHandler)
}
}
2.使用注解,注册跳转路径
@RouterUri(
path = ["/TestBasicActivity"]
)
class TestBasicActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
title = "Basic activity"
setContentView(R.layout.activity_test_basic)
}
}
3.跳转到指定界面
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnJump.setOnClickListener {
Router.startUri(this, "/TestBasicActivity")
}
}
}
我们先看一下步骤2.使用注解,注册跳转路径
在使用注解注册跳转路径以后,build一下工程,可以在WMRouterDemo/app/build/generated/source/kapt/debug/com/sankuai/waimai/router/generated/
目录下找到注解自动生成的文件。
package com.sankuai.waimai.router.generated.service;
import com.sankuai.waimai.router.common.IUriAnnotationInit;
import com.sankuai.waimai.router.service.ServiceLoader;
public class ServiceInit_4febd0b5ae00b38c8960bbb78d73389d {
public static void init() {
ServiceLoader.put(IUriAnnotationInit.class, "com.sankuai.waimai.router.generated.UriAnnotationInit_7faf56b0e560a0b80e7feccbda06ab16", com.sankuai.waimai.router.generated.UriAnnotationInit_7faf56b0e560a0b80e7feccbda06ab16.class, false);
}
}
UriAnnotationInit_7faf56b0e560a0b80e7feccbda06ab16.java
package com.sankuai.waimai.router.generated;
import com.dmw.wmrouterdemo.advanced.abtest.HomeABTestHandler;
import com.dmw.wmrouterdemo.advanced.account.LoginInterceptor;
import com.sankuai.waimai.router.common.IUriAnnotationInit;
import com.sankuai.waimai.router.common.UriAnnotationHandler;
public class UriAnnotationInit_7faf56b0e560a0b80e7feccbda06ab16 implements IUriAnnotationInit {
public void init(UriAnnotationHandler handler) {
//调用UriAnnotationHandler的register方法
handler.register("", "", "/TestBasicActivity",
"com.dmw.wmrouterdemo.activity.TestBasicActivity", false);
}
}
我们看一下UriAnnotationHandler的register方法中都做了哪些操作,注意我们传入的handler参数是一个字符串com.dmw.wmrouterdemo.activity.TestBasicActivity
。
/**
* @params handler
* @params exported 是否允许外部跳转 默认是false
*/
public void register(String scheme, String host, String path,Object handler,
boolean exported, UriInterceptor... interceptors) {
// 没配scheme和host使用默认值
if (TextUtils.isEmpty(scheme)) {
scheme = mDefaultScheme;
}
if (TextUtils.isEmpty(host)) {
host = mDefaultHost;
}
//拼接成scheme://host
String schemeHost = RouterUtils.schemeHost(scheme, host);
//获取路径处理者,如果为null,则创建并保存在map中
PathHandler pathHandler = mMap.get(schemeHost);
if (pathHandler == null) {
//注释1处,创建处理者
pathHandler = createPathHandler();
//加入到map中
mMap.put(schemeHost, pathHandler);
}
//注释2处
pathHandler.register(path, handler, exported, interceptors);
}
在注释1处,UriAnnotationHandler的createPathHandler方法
protected PathHandler createPathHandler() {
PathHandler pathHandler = new PathHandler();
if (sAddNotFoundHandler) {//默认是true
pathHandler.setDefaultChildHandler(NotFoundHandler.INSTANCE);
}
return pathHandler;
}
注意一下 sAddNotFoundHandler 这个变量,默认为true。如果 sAddNotFoundHandler 为 true,则给 PathHandler 上添加一个 NotFoundHandler 。如果添加了 NotFoundHandler ,则只要scheme+host
能够匹配上,所有的URI都会被 PathHandler 处理,即使path不能匹配,也会分发到 NotFoundHandler 终止分发。
createPathHandler方法构建了一个PathHandler对象,并且该对象添加了一个默认的子处理者,一个NotFoundHandler
对象。然后把这个PathHandler对象加入到了UriAnnotationHandler的map中。
UriAnnotationHandler的mMap对象
/**
* key是由scheme+host生成的字符串,value是PathHandler。
*/
private final Map mMap = new HashMap<>();
在上面方法的注释2处,调用了PathHandler的register方法。
/**
* 注册一个子节点
*
* @param path path
* @param target 支持ActivityClassName、ActivityClass、UriHandler
* @param exported 是否允许外部跳转
* @param interceptors 要添加的interceptor
*/
public void register(String path, Object target, boolean exported,
UriInterceptor... interceptors) {
if (!TextUtils.isEmpty(path)) {
//如果path不是以反斜杠开头,则添加反斜杠
path = RouterUtils.appendSlash(path);
//注释1处
UriHandler parse = UriTargetTools.parse(target, exported, interceptors);
UriHandler prev = mMap.put(path, parse);
if (prev != null) {
Debugger.fatal("[%s] 重复注册path='%s'的UriHandler: %s, %s",
this, path, prev, parse);
}
}
}
在PathHandler的register方法的注释1处,调用了UriTargetTools的parse方法
public static UriHandler parse(Object target, boolean exported,
UriInterceptor... interceptors) {
//注释1处
UriHandler handler = toHandler(target);
if (handler != null) {
if (!exported) {//添加NotExportedInterceptor
handler.addInterceptor(NotExportedInterceptor.INSTANCE);
}
handler.addInterceptors(interceptors);
}
return handler;
}
在UriTargetTools的parse方法的注释1处,调用了toHandler方法
private static UriHandler toHandler(Object target) {
if (target instanceof UriHandler) {
return (UriHandler) target;
} else if (target instanceof String) {
return new ActivityClassNameHandler((String) target);
} else if (target instanceof Class && isValidActivityClass((Class) target)) {
//noinspection unchecked
return new ActivityHandler((Class extends Activity>) target);
} else {
return null;
}
}
在这个例子中我们的target是String类型对象com.dmw.wmrouterdemo.activity.TestBasicActivity
,所以会返回一个ActivityClassNameHandler对象。然后给这个ActivityClassNameHandler对象添加了一个NotExportedInterceptor拦截器,不允许外部跳转。
UriHandler类的addInterceptor方法
protected ChainedInterceptor mInterceptor;
public UriHandler addInterceptor(UriInterceptor interceptor) {
if (interceptor != null) {
if (mInterceptor == null) {
mInterceptor = new ChainedInterceptor();
}
mInterceptor.addInterceptor(interceptor);
}
return this;
}
最后我们把这个ActivityClassNameHandler对象,加入到了PathHandler的mMap对象中。
PathHandler的mMap对象
private final CaseInsensitiveNonNullMap mMap = new CaseInsensitiveNonNullMap<>();
到这里步骤2结束,在这个例子中UriAnnotationHandler的register方法调用完毕后,初始化了如下图所示的对象。
至于UriAnnotationHandler的register方法何时会被调用,我们后面再说。
现在看一下第1步,初始化过程。
val rootUriHandler = DefaultRootUriHandler(this)
Router.init(rootUriHandler)
DefaultRootUriHandler的继承结构
DefaultRootUriHandler部分代码
public class DefaultRootUriHandler extends RootUriHandler {
//@RouterPage的注解处理器
private final PageAnnotationHandler mPageAnnotationHandler;
//RouterUri的注解处理器
private final UriAnnotationHandler mUriAnnotationHandler;
//RouterRegex的注解处理器
private final RegexAnnotationHandler mRegexAnnotationHandler;
public DefaultRootUriHandler(Context context) {
this(context, null, null);
}
/**
* @param defaultScheme {@link RouterUri} 没有指定scheme时,则使用这里设置的defaultScheme
* @param defaultHost {@link RouterUri} 没有指定host时,则使用这里设置的defaultHost
*/
public DefaultRootUriHandler(Context context, String defaultScheme,
String defaultHost) {
super(context);
mPageAnnotationHandler = createPageAnnotationHandler();
//注意这里创建的是一个UriAnnotationHandler对象
mUriAnnotationHandler = createUriAnnotationHandler(defaultScheme, defaultHost);
mRegexAnnotationHandler = createRegexAnnotationHandler();
// 按优先级排序,数字越大越先执行,
//可以看到优先级:RouterPage>RouterUri>RouterRegex>StartUriHandler
// 处理RouterPage注解定义的内部页面跳转,如果注解没定义,直接结束分发
addChildHandler(mPageAnnotationHandler, 300);
// 处理RouterUri注解定义的URI跳转,如果注解没定义,继续分发到后面的Handler
addChildHandler(mUriAnnotationHandler, 200);
// 处理RouterRegex注解定义的正则匹配
addChildHandler(mRegexAnnotationHandler, 100);
// 添加其他用户自定义Handler...
// 都没有处理,则尝试使用默认的StartUriHandler直接启动Uri
addChildHandler(new StartUriHandler(), -100);
//注释1处, 全局OnCompleteListener,用于输出跳转失败提示信息
setGlobalOnCompleteListener(DefaultOnCompleteListener.INSTANCE);
}
//...
}
我们看一下addChildHandler方法,这个方法是在ChainedHandler中定义的。
//存放处理者
private final PriorityList mHandlers = new PriorityList<>();
/**
* 添加一个Handler
*
* @param priority 优先级。优先级越大越先执行;相同优先级,先加入的先执行。
*/
public ChainedHandler addChildHandler(@NonNull UriHandler handler, int priority) {
//添加处理者
mHandlers.addItem(handler, priority);
return this;
}
addChildHandler方法会对传入的UriHandler按照优先级进行排序,优先级越大越先执行;相同优先级,先加入的先执行。我们一共添加了4个处理者,按照优先级排序是
PageAnnotationHandler > UriAnnotationHandler > RegexAnnotationHandler > StartUriHandler 。
在DefaultRootUriHandler的构造函数的注释1处,设置了一个全局OnCompleteListener,用于输出跳转失败提示信息。
Router的init方法
private static RootUriHandler ROOT_HANDLER;
/**
* 此初始化方法必须在主线程调用。
*/
public static void init(RootUriHandler rootUriHandler) {
if (Looper.myLooper() != Looper.getMainLooper()) {
Debugger.fatal("初始化方法init应该在主线程调用");
}
if (ROOT_HANDLER == null) {
ROOT_HANDLER = rootUriHandler;
} else {
Debugger.fatal("请勿重复初始化UriRouter");
}
}
就是给ROOT_HANDLER赋值为我们先前创建的DefaultRootUriHandler对象。
然后看第3步,路由分发
先看一下大致的流程图
Router.startUri(this, "/TestBasicActivity")
public static void startUri(Context context, String uri) {
//构建一个UriRequest,然后调用DefaultRootUriHandler的startUri方法
getRootHandler().startUri(new UriRequest(context, uri));
}
getRootHandler()获取的是我们传入的的DefaultRootUriHandler对象。DefaultRootUriHandler继承了RootUriHandler,startUri方法是在RootUriHandler类中声明的。
RootUriHandler的startUri方法
public void startUri(UriRequest request) {
if (request == null) {//注释1处,
String msg = "UriRequest为空";
Debugger.fatal(msg);
UriRequest req = new UriRequest(mContext, Uri.EMPTY).setErrorMessage(msg);
onError(req, UriResult.CODE_BAD_REQUEST);
} else if (request.getContext() == null) {//注释2处
String msg = "UriRequest.Context为空";
Debugger.fatal(msg);
UriRequest req = new UriRequest(mContext, request.getUri(), request.getFields())
.setErrorMessage(msg);
onError(req, UriResult.CODE_BAD_REQUEST);
} else if (request.isUriEmpty()) {//注释3处
String msg = "跳转链接为空";
Debugger.e(msg);
request.setErrorMessage(msg);
onError(request, UriResult.CODE_BAD_REQUEST);
} else {
if (Debugger.isEnableLog()) {
Debugger.i("");
Debugger.i("---> receive request: %s", request.toFullString());
}
//注释4处
handle(request, new RootUriCallback(request));
}
}
注释1,2,3处都是为了处理异常情况,我们先看看onError方法。
private void onError(UriRequest request, int resultCode) {
OnCompleteListener globalListener = mGlobalOnCompleteListener;
if (globalListener != null) {
globalListener.onError(request, resultCode);
}
final OnCompleteListener listener = request.getOnCompleteListener();
if (listener != null) {
listener.onError(request, resultCode);
}
}
在这个方法里面,如果设置了全局的OnCompleteListener,首先是调用全局的OnCompleteListener的onError方法,如果request设置了OnCompleteListener,则调用request的onError方法。我们在初始化Router的时候设置了的全局OnCompleteListener是一个DefaultOnCompleteListener对象。
DefaultOnCompleteListener的onError方法,只是给出了一个toast提示。
@Override
public void onError(UriRequest request, int resultCode) {
String text = request.getStringField(UriRequest.FIELD_ERROR_MSG, null);
if (TextUtils.isEmpty(text)) {
switch (resultCode) {
case CODE_NOT_FOUND:
text = "不支持的跳转链接";
break;
case CODE_FORBIDDEN:
text = "没有权限";
break;
default:
text = "跳转失败";
break;
}
}
text += "(" + resultCode + ")";
if (Debugger.isEnableDebug()) {
text += "\n" + request.getUri().toString();
}
Toast.makeText(request.getContext(), text, Toast.LENGTH_LONG).show();
}
我们接下来看RootUriHandler的startUri方法的注释4处,调用handle方法。
handle(request, new RootUriCallback(request));
首先使用传入的request构建了一个RootUriCallback对象。
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:
// 重定向,重新跳转
Debugger.i("<--- redirect, result code = %s", resultCode);
startUri(mRequest);
break;
case CODE_SUCCESS:
// 跳转成功
mRequest.putField(UriRequest.FIELD_RESULT_CODE, resultCode);
onSuccess(mRequest);
Debugger.i("<--- success, result code = %s", resultCode);
break;
default:
// 跳转失败
mRequest.putField(UriRequest.FIELD_RESULT_CODE, resultCode);
onError(mRequest, resultCode);
Debugger.i("<--- error, result code = %s", resultCode);
break;
}
}
}
接下来看handle方法,这个方法是在UriHandler类中定义的。
/**
* 处理URI。通常不需要覆写本方法。
*
* @param request URI跳转请求
* @param callback 处理完成后的回调
*/
public void handle(final UriRequest request, final UriCallback callback) {
if (shouldHandle(request)) {//注释1处,如果应该处理
Debugger.i("%s: handle request %s", this, request);
if (mInterceptor != null && !request.isSkipInterceptors()) {
//注释2处
mInterceptor.intercept(request, new UriCallback() {
@Override
public void onNext() {
handleInternal(request, callback);
}
@Override
public void onComplete(int result) {
callback.onComplete(result);
}
});
} else {
//注释3处
handleInternal(request, callback);
}
} else {
Debugger.i("%s: ignore request %s", this, request);
callback.onNext();
}
}
在上面方法的注释1处,判断是否要处理给定的URI。ChainedHandler覆盖了这个方法,我们看一下。
private final PriorityList mHandlers = new PriorityList<>();
protected boolean shouldHandle(UriRequest request) {
return !mHandlers.isEmpty();
}
开始我们在初始化DefaultRootUriHandler的时候一共添加了4个UriHandler,所以这里shouldHandle是返回true的。
我们回到UriHandler类的handle方法的注释2处,这里判断如果添加了拦截器并且不跳过拦截器,则先由拦截器处理URI。我们在初始化DefaultRootUriHandler是没有添加拦截器的。所以会走到注释3处。
handleInternal(request, callback);
handleInternal方法是UriHandler中定义的一个抽象方法,ChainedHandler实现了这个方法。
@Override
protected void handleInternal(final UriRequest request, final UriCallback callback) {
//调用next方法
next(mHandlers.iterator(), request, callback);
}
private void next(final Iterator iterator, final UriRequest request,
final UriCallback callback) {
if (iterator.hasNext()) {
UriHandler t = iterator.next();
//执行,并传入一个UriCallback对象。
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从ChainedHandler中取出UriHandler依次执行UriHandler的handle方法。在上面初始化DefaultRootUriHandler的时候按照优先级依次是PageAnnotationHandler > UriAnnotationHandler > RegexAnnotationHandler > StartUriHandler 。
PageAnnotationHandler的handle方法
public void handle(UriRequest request, UriCallback callback) {
mInitHelper.ensureInit();//先确Router保初始化完毕
super.handle(request, callback);
}
我们看到 PageAnnotationHandler的handle方法又调用了父类UriHandler的handle方法。
public void handle(final UriRequest request, final UriCallback callback) {
if (shouldHandle(request)) {
Debugger.i("%s: handle request %s", this, 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 {
Debugger.i("%s: ignore request %s", this, request);
//不应该处理,则调用callback的onNext方法。
callback.onNext();
}
}
这个时候shouldHandle条件是不满足的,PageAnnotationHandler只能处理schema+host是wm_router://page
public static final String SCHEME = "wm_router";
public static final String HOST = "page";
//拼接成 wm_router://page
public static final String SCHEME_HOST = RouterUtils.schemeHost(SCHEME, HOST);
protected boolean shouldHandle(UriRequest request) {
return SCHEME_HOST.matches(request.schemeHost());
}
PageAnnotationHandler不会处理,所以会调用传入的callback的onNext方法,回到ChainedHandler的next方法。请记住,next方法的callback参数就是开始传入的RootUriCallback对象。
private void next(final Iterator iterator, final UriRequest request,
final UriCallback callback) {
if (iterator.hasNext()) {
UriHandler t = iterator.next();
//执行,并传入一个UriCallback对象。
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();
}
}
接下来会取出UriAnnotationHandler来执行handle方法。
UriAnnotationHandler的handle方法
public void handle(UriRequest request, UriCallback callback) {
mInitHelper.ensureInit();
super.handle(request, callback);
}
同样的套路,也是先保证Router初始化完毕,然后调用父类UriHandler的handle方法。
这个时候UriAnnotationHandler的shouldHandle方法是返回true的,所以由UriAnnotationHandler来处理
@Override
protected boolean shouldHandle(UriRequest request) {
return getChild(request) != null;
}
//通过scheme+host找对应的PathHandler,找到了才会处理
private PathHandler getChild(UriRequest request) {
return mMap.get(request.schemeHost());
}
UriAnnotationHandler是没有添加拦截器的,所以会调用handleInternal方法
UriAnnotationHandler的handleInternal方法
@Override
protected void handleInternal(UriRequest request, UriCallback callback) {
//根据请求路径获取PathHandler
PathHandler pathHandler = getChild(request);
if (pathHandler != null) {
pathHandler.handle(request, callback);
} else {
// 没找到的继续分发
callback.onNext();
}
}
首先获取PathHandler,然后调用PathHandler的handle方法
PathHandler的handle方法
PathHandler的shouldHandle方法
@Override
protected boolean shouldHandle(UriRequest request) {
return mDefaultHandler != null || getChild(request) != null;
}
private UriHandler getChild(UriRequest request) {
String path = request.getUri().getPath();
if (TextUtils.isEmpty(path)) {
return null;
}
path = RouterUtils.appendSlash(path);
if (TextUtils.isEmpty(mPathPrefix)) {
return mMap.get(path);
}
if (path.startsWith(mPathPrefix)) {
return mMap.get(path.substring(mPathPrefix.length()));
}
return null;
}
我们在初始化的时候给PathHandler添加了一个mDefaultHandler(NotFoundHandler),并且getChild(request)会返回我们开始添加的ActivityClassNameHandler对象。所以shouldHandle返回true。然后PathHandler没有添加拦截器,所以会调用handleInternal方法。
@Override
protected void handleInternal(final UriRequest request,final UriCallback callback) {
//注释1处,
UriHandler h = getChild(request);
if (h != null) {
h.handle(request, new UriCallback() {
@Override
public void onNext() {
handleByDefault(request, callback);
}
@Override
public void onComplete(int resultCode) {
callback.onComplete(resultCode);
}
});
} else {
handleByDefault(request, callback);
}
}
上面注释1处,会返回我们开始添加的ActivityClassNameHandler对象,接下来会调用ActivityClassNameHandler的handle方法。
ActivityClassNameHandler的handle方法
我们先看一下ActivityClassNameHandler的继承结构图
ActivityClassNameHandler的handle方法还是调用UriHandler的handle方法
public void handle(final UriRequest request, final UriCallback callback) {
if (shouldHandle(request)) {
Debugger.i("%s: handle request %s", this, request);
if (mInterceptor != null && !request.isSkipInterceptors()) {
//注释1处,ActivityClassNameHandler是添加了拦截器的
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 {
Debugger.i("%s: ignore request %s", this, request);
//不应该处理,则调用callback的onNext方法。
callback.onNext();
}
}
ActivityClassNameHandler的shouldHandle方法直接返回true。
@Override
protected boolean shouldHandle(UriRequest request) {
//直接return true
return true;
}
我们在初始化ActivityClassNameHandler的时候添加了一个NotExportedInterceptor对象。我们是把这个对象加入到了ChainedInterceptor,所以会调用ChainedInterceptor的intercept方法。
ChainedInterceptor的intercept方法。
private final List mInterceptors = new LinkedList<>();
@Override
public void intercept(UriRequest request, UriCallback callback) {
next(mInterceptors.iterator(), request, callback);
}
private void next(final Iterator iterator, final UriRequest request,
final UriCallback callback) {
if (iterator.hasNext()) {
UriInterceptor t = iterator.next();
t.intercept(request, new UriCallback() {
@Override
public void onNext() {
next(iterator, request, callback);
}
@Override
public void onComplete(int resultCode) {
callback.onComplete(resultCode);
}
});
} else {
callback.onNext();
}
}
我们只添加了一个NotExportedInterceptor,我们直接去看NotExportedInterceptor的intercept方法。
@Override
public void intercept(UriRequest request, UriCallback callback) {
if (UriSourceTools.shouldHandle(request, false)) {
callback.onNext();
} else {
callback.onComplete(UriResult.CODE_FORBIDDEN);
}
}
因为在这个例子中我们是内部跳转,所以会调用callback.onNext();
。然后回到
ChainedInterceptor的next方法中,在这个时候已经没有下一个拦截器,所以会调用callback.onNext();
回到ActivityClassNameHandler的handleInternal方法。
AbsActivityHandler的handleInternal方法。
@Override
protected void handleInternal(UriRequest request, UriCallback callback) {
// 创建Intent
Intent intent = createIntent(request);
if (intent == null || intent.getComponent() == null) {
Debugger.fatal("AbsActivityHandler.createIntent()应返回的带有ClassName的显式跳转Intent");
callback.onComplete(UriResult.CODE_ERROR);
return;
}
intent.setData(request.getUri());
UriSourceTools.setIntentSource(intent, request);
// 启动Activity
request.putFieldIfAbsent(ActivityLauncher.FIELD_LIMIT_PACKAGE, limitPackage());
//启动Activity
int resultCode = RouterComponents.startActivity(request, intent);
// 回调方法
onActivityStartComplete(request, resultCode);
// 完成
callback.onComplete(resultCode);
}
这里就是使用RouterComponents启动Activity,然后调用 callback.onComplete(resultCode);
最后callback是回到了我们在RootUriHandler的startUri方法中传入的RootUriCallback。
RootUriCallback的onComplete方法。
@Override
public void onComplete(int resultCode) {
switch (resultCode) {
case CODE_REDIRECT:
// 重定向,重新跳转
Debugger.i("<--- redirect, result code = %s", resultCode);
startUri(mRequest);
break;
case CODE_SUCCESS:
// 跳转成功
mRequest.putField(UriRequest.FIELD_RESULT_CODE, resultCode);
onSuccess(mRequest);
Debugger.i("<--- success, result code = %s", resultCode);
break;
default:
// 跳转失败
mRequest.putField(UriRequest.FIELD_RESULT_CODE, resultCode);
onError(mRequest, resultCode);
Debugger.i("<--- error, result code = %s", resultCode);
break;
}
}
如果跳转成功
private void onSuccess(UriRequest request) {
OnCompleteListener globalListener = mGlobalOnCompleteListener;
if (globalListener != null) {
globalListener.onSuccess(request);
}
final OnCompleteListener listener = request.getOnCompleteListener();
if (listener != null) {
listener.onSuccess(request);
}
}
在这个方法里面,如果设置了全局的OnCompleteListener,首先是调用全局的OnCompleteListener的onSuccess方法,如果request设置了OnCompleteListener,则调用request的onSuccess方法。我们在初始化Router的时候设置了的全局OnCompleteListener是一个DefaultOnCompleteListener对象。
DefaultOnCompleteListener的onSuccess方法什么也没做。
@Override
public void onSuccess(UriRequest request) {
}
遗留的问题
到这里还剩下一个问题ServiceInit的init方法是何时被调用的,因为只有调用了这个方法才会调用UriAnnotationHandler的register方法,完成UriAnnotationHandler的初始化工作。先看流程图。
这个初始化的时机就是我们调用UriAnnotationHandler的handle的方法的时候调用的LazyInitHelper的ensureInit方法。
UriAnnotationHandler的handle方法
@Override
public void handle(UriRequest request, UriCallback callback) {
//注释1处
mInitHelper.ensureInit();
super.handle(request, callback);
}
ensureInit会确保doInit方法被调用
private final LazyInitHelper mInitHelper = new LazyIni tHelper("UriAnnotationHandler") {
@Override
protected void doInit() {
initAnnotationConfig();
}
};
protected void initAnnotationConfig() {
//传入UriAnnotationHandler.this
RouterComponents.loadAnnotation(this, IUriAnnotationInit.class);
}
RouterComponents类
private static AnnotationLoader sAnnotationLoader = DefaultAnnotationLoader.INSTANCE;
public static void loadAnnotation(T handler, Class extends AnnotationInit> initClass) {
sAnnotationLoader.load(handler, initClass);
}
DefaultAnnotationLoader类
public class DefaultAnnotationLoader implements AnnotationLoader {
public static final AnnotationLoader INSTANCE = new DefaultAnnotationLoader();
@Override
public void load(T handler,
Class extends AnnotationInit> initClass) {
//注释1处,创建IUriAnnotationInit接口所有的实现类的实例
List extends AnnotationInit> services = Router.getAllServices(initClass);
//注释2处
for (AnnotationInit service : services) {
//传入handler实例
service.init(handler);
}
}
}
在上面的注释1处,调用了Router的getAllServices方法,创建传入的class对象的所有实现类的实例。
public static List getAllServices(Class clazz) {
return ServiceLoader.load(clazz).getAll();
}
那么这个时候,UriAnnotationInit_7faf56b0e560a0b80e7feccbda06ab16类的实例就会被创建。然后在注释2处,调用了init方法,调用UriAnnotationHandler的register方法,完成UriAnnotationHandler的初始化操作。
public class UriAnnotationInit_7faf56b0e560a0b80e7feccbda06ab16 implements IUriAnnotationInit {
public void init(UriAnnotationHandler handler) {
handler.register("", "", "/TestBasicActivity", "com.dmw.wmrouterdemo.activity.TestBasicActivity", false);
}
}
ServiceLoader使用及原理分析
ServiceLoader跟DriverManager使用总结
WMRouter