WMRouter源码学习

我们以一个最简单的使用场景来分析。

三部曲

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) 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

至于UriAnnotationHandler的register方法何时会被调用,我们后面再说。

现在看一下第1步,初始化过程。

val rootUriHandler = DefaultRootUriHandler(this)
Router.init(rootUriHandler)

DefaultRootUriHandler的继承结构


DefaultRootUriHandler.png

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().jpg
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.png

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的初始化工作。先看流程图。


LazyInitHelper (1).jpg

这个初始化的时机就是我们调用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> 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> initClass) {
        //注释1处,创建IUriAnnotationInit接口所有的实现类的实例
        List> 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);
  }
}

  1. ServiceLoader使用及原理分析

  2. ServiceLoader跟DriverManager使用总结

  3. WMRouter

你可能感兴趣的:(WMRouter源码学习)