Android-ARouter拦截器和IProvider解析

一、interceptor

使用ARouter的拦截器的话,会生成对应的ARouter$$Providers$${模块名}的class类,比如:

public class ARouter$$Interceptors$$aroutercomponent implements IInterceptorGroup {
  @Override
  public void loadInto(Map<Integer, Class<? extends IInterceptor>> interceptors) {
    interceptors.put(8, LoginInterceptor.class);
  }
}

在这里interceptors这个map集合中,以拦截器的优先级作为key,拦截器的class作为value。定义拦截器的时候,并不会封装成RouteMeta对象进行保存。

二、IProvider

在ARouter中,service其实也是继承自IProvider的接口,比如PathReplaceService、PretreatmentService、SerializationService等,都是继承了IProvider的。
而IProvider的实现类,会被包装成RouteMeta对象,包装在ARouter$$Group$${组名}中,并且还会在ARouter$$Providers$${模块名}中定义一份。

public class ARouter$$Group$$serializableservice implements IRouteGroup {
  @Override
  public void loadInto(Map<String, RouteMeta> atlas) {
    atlas.put("/serializableservice/hello", RouteMeta.build(RouteType.PROVIDER, HelloServiceImpl.class, "/serializableservice/hello", "serializableservice", null, -1, -2147483648));
    atlas.put("/serializableservice/json", RouteMeta.build(RouteType.PROVIDER, JsonServiceImpl.class, "/serializableservice/json", "serializableservice", null, -1, -2147483648));
    atlas.put("/serializableservice/pathReplace", RouteMeta.build(RouteType.PROVIDER, PathReplaceServiceImpl.class, "/serializableservice/pathreplace", "serializableservice", null, -1, -2147483648));
    atlas.put("/serializableservice/pretreatment", RouteMeta.build(RouteType.PROVIDER, PretreatmentServiceImpl.class, "/serializableservice/pretreatment", "serializableservice", null, -1, -2147483648));
  }
}
public class ARouter$$Providers$$ARouterBase implements IProviderGroup {
  @Override
  public void loadInto(Map<String, RouteMeta> providers) {
    providers.put("com.nene.arouterbase.service.HelloService", RouteMeta.build(RouteType.PROVIDER, HelloServiceImpl.class, "/serializableservice/hello", "serializableservice", null, -1, -2147483648));
    providers.put("com.alibaba.android.arouter.facade.service.SerializationService", RouteMeta.build(RouteType.PROVIDER, JsonServiceImpl.class, "/serializableservice/json", "serializableservice", null, -1, -2147483648));
    providers.put("com.alibaba.android.arouter.facade.service.PathReplaceService", RouteMeta.build(RouteType.PROVIDER, PathReplaceServiceImpl.class, "/serializableservice/pathReplace", "serializableservice", null, -1, -2147483648));
    providers.put("com.alibaba.android.arouter.facade.service.PretreatmentService", RouteMeta.build(RouteType.PROVIDER, PretreatmentServiceImpl.class, "/serializableservice/pretreatment", "serializableservice", null, -1, -2147483648));
  }
}

其实ARouter中的service,根据不同的Service来实现不同的操作,比如PretreatmentService预处理服务,在调用navigation的时候,就会先判断预处理服务是否为空,并且是否返回了false,如果是返回了false,则会在navigation中返回一个null。

_ARouter.navigation
    protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
        PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);
        if (null != pretreatmentService && !pretreatmentService.onPretreatment(context, postcard)) {
            // Pretreatment failed, navigation canceled.
            return null;
        }
        ...
    }
PathReplaceService

而PathReplaceService的处理,其实就是在application对ARouter初始化的时候,会初始化一个InterceptorService,那么在这个时候就会判断path是否需要替换。
而Activity的path是否需要被替换,则是通过在调用ARouter.getInstance().build("/news/news")的时候

// ARouter.java
    public Postcard build(String path) {
        return _ARouter.getInstance().build(path);
    }
// _ARouter.java
    protected Postcard build(String path) {
        if (TextUtils.isEmpty(path)) {
            throw new HandlerException(Consts.TAG + "Parameter is invalid!");
        } else {
            PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
            if (null != pService) {
                path = pService.forString(path);
            }
            return build(path, extractGroup(path), true);
        }
    }
SerializationService

SerializationService的调用,则是在Postcard调用withObject的时候,获取到该service,然后通过该service的object2Json和parseObject来对数据进行处理。
parseObject的调用,其实就是在针对对应的Activity的属性注解@Autowired的做处理的时候

public class NewsDesActivity$$ARouter$$Autowired implements ISyringe {
  private SerializationService serializationService;

  @Override
  public void inject(Object target) {
    serializationService = ARouter.getInstance().navigation(SerializationService.class);
    NewsDesActivity substitute = (NewsDesActivity)target;
    if (null != serializationService) {
      substitute.newsBean = serializationService.parseObject(substitute.getIntent().getStringExtra("newsBean"), new com.alibaba.android.arouter.facade.model.TypeWrapper<NewsBean>(){}.getType());
    } else {
      Log.e("ARouter::", "You want automatic inject the field 'newsBean' in class 'NewsDesActivity' , then you should implement 'SerializationService' to support object auto inject!");
    }
  }
}
ARouter的属性注入

ARouter的属性注入,还是需要在Activity中主动调用ARouter.getInstance().inject(this)
然后在这里会创建一个AutowiredService对象,用这个服务对象来处理ISyringe,其实就是对应的Autowired,如下:

public class NewsDesActivity$$ARouter$$Autowired implements ISyringe {
  private SerializationService serializationService;

  @Override
  public void inject(Object target) {
    serializationService = ARouter.getInstance().navigation(SerializationService.class);
    NewsDesActivity substitute = (NewsDesActivity)target;
    if (null != serializationService) {
      substitute.newsBean = serializationService.parseObject(substitute.getIntent().getStringExtra("newsBean"), new com.alibaba.android.arouter.facade.model.TypeWrapper<NewsBean>(){}.getType());
    } else {
      Log.e("ARouter::", "You want automatic inject the field 'newsBean' in class 'NewsDesActivity' , then you should implement 'SerializationService' to support object auto inject!");
    }
  }
}

在这里就会调用ISyringe的inject方法,就可以对对应的Activity(其实就是传给inject方法的参数target)属性注入对应的值,这些属性不能是私有的,否则就不能直接通过对应的Activity对象直接拿到属性。

三、初始化流程解析拦截器和IProvider

1.ARouter.init(this);

在Application的onCreate方法中,调用进行初始化,其内部实现如下:

    public static void init(Application application) {
        if (!hasInit) {
            logger = _ARouter.logger;
            _ARouter.logger.info(Consts.TAG, "ARouter init start.");
            hasInit = _ARouter.init(application);

            if (hasInit) {
                _ARouter.afterInit();
            }

            _ARouter.logger.info(Consts.TAG, "ARouter init over.");
        }
    }

而_ARouter.init(application);是初始化Warehouse中的各个集合的缓存内容,将每个分组、Interceptor、Provider根据分组名和模块名进行文件的分别保存。
在初始化完成之后,就会调用_ARouter.afterInit();

2._ARouter.afterInit();

这里会初始化一个InterceptorService,这个是在ARouter-api中的InterceptorServiceImpl,如下所示:

ARouter-api中的InterceptorServiceImpl
@Route(path = "/arouter/service/interceptor")
public class InterceptorServiceImpl implements InterceptorService {
    private static boolean interceptorHasInit;
    private static final Object interceptorInitLock = new Object();

    @Override
    public void doInterceptions(final Postcard postcard, final InterceptorCallback callback) {
        if (null != Warehouse.interceptors && Warehouse.interceptors.size() > 0) {

            checkInterceptorsInitStatus();

            if (!interceptorHasInit) {
                callback.onInterrupt(new HandlerException("Interceptors initialization takes too much time."));
                return;
            }

            LogisticsCenter.executor.execute(new Runnable() {
                @Override
                public void run() {
                    CancelableCountDownLatch interceptorCounter = new CancelableCountDownLatch(Warehouse.interceptors.size());
                    try {
                        _execute(0, interceptorCounter, postcard);
                        interceptorCounter.await(postcard.getTimeout(), TimeUnit.SECONDS);
                        if (interceptorCounter.getCount() > 0) {    // Cancel the navigation this time, if it hasn't return anythings.
                            callback.onInterrupt(new HandlerException("The interceptor processing timed out."));
                        } else if (null != postcard.getTag()) {    // Maybe some exception in the tag.
                            callback.onInterrupt(new HandlerException(postcard.getTag().toString()));
                        } else {
                            callback.onContinue(postcard);
                        }
                    } catch (Exception e) {
                        callback.onInterrupt(e);
                    }
                }
            });
        } else {
            callback.onContinue(postcard);
        }
    }

    /**
     * Excute interceptor
     *
     * @param index    current interceptor index
     * @param counter  interceptor counter
     * @param postcard routeMeta
     */
    private static void _execute(final int index, final CancelableCountDownLatch counter, final Postcard postcard) {
        if (index < Warehouse.interceptors.size()) {
            IInterceptor iInterceptor = Warehouse.interceptors.get(index);
            iInterceptor.process(postcard, new InterceptorCallback() {
                @Override
                public void onContinue(Postcard postcard) {
                    // Last interceptor excute over with no exception.
                    counter.countDown();
                    _execute(index + 1, counter, postcard);  // When counter is down, it will be execute continue ,but index bigger than interceptors size, then U know.
                }

                @Override
                public void onInterrupt(Throwable exception) {
                    // Last interceptor excute over with fatal exception.

                    postcard.setTag(null == exception ? new HandlerException("No message.") : exception.getMessage());    // save the exception message for backup.
                    counter.cancel();
                    // Be attention, maybe the thread in callback has been changed,
                    // then the catch block(L207) will be invalid.
                    // The worst is the thread changed to main thread, then the app will be crash, if you throw this exception!
//                    if (!Looper.getMainLooper().equals(Looper.myLooper())) {    // You shouldn't throw the exception if the thread is main thread.
//                        throw new HandlerException(exception.getMessage());
//                    }
                }
            });
        }
    }

    @Override
    public void init(final Context context) {
        LogisticsCenter.executor.execute(new Runnable() {
            @Override
            public void run() {
                if (MapUtils.isNotEmpty(Warehouse.interceptorsIndex)) {
                    for (Map.Entry<Integer, Class<? extends IInterceptor>> entry : Warehouse.interceptorsIndex.entrySet()) {
                        Class<? extends IInterceptor> interceptorClass = entry.getValue();
                        try {
                            IInterceptor iInterceptor = interceptorClass.getConstructor().newInstance();
                            iInterceptor.init(context);
                            Warehouse.interceptors.add(iInterceptor);
                        } catch (Exception ex) {
                            throw new HandlerException(TAG + "ARouter init interceptor error! name = [" + interceptorClass.getName() + "], reason = [" + ex.getMessage() + "]");
                        }
                    }

                    interceptorHasInit = true;

                    logger.info(TAG, "ARouter interceptors init over.");

                    synchronized (interceptorInitLock) {
                        interceptorInitLock.notifyAll();
                    }
                }
            }
        });
    }

    private static void checkInterceptorsInitStatus() {
        synchronized (interceptorInitLock) {
            while (!interceptorHasInit) {
                try {
                    interceptorInitLock.wait(10 * 1000);
                } catch (InterruptedException e) {
                    throw new HandlerException(TAG + "Interceptor init cost too much time error! reason = [" + e.getMessage() + "]");
                }
            }
        }
    }
}
_ARouter.afterInit()
    static void afterInit() {
        // Trigger interceptor init, use byName.
        interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor").navigation();
    }

ARouter.getInstance().build("/arouter/service/interceptor")会返回一个Postcard对象,并且给Postcard的group和path赋值为arouter、/arouter/service/interceptor

    protected Postcard build(String path) {
        if (TextUtils.isEmpty(path)) {
            throw new HandlerException(Consts.TAG + "Parameter is invalid!");
        } else {
            PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
            if (null != pService) {
                path = pService.forString(path);
            }
            return build(path, extractGroup(path), true);
        }
    }

extractGroup方法就是在没有单独定义group的值的时候,从path中取出第一个/后面的第一串字符串作为group

    private String extractGroup(String path) {
        if (TextUtils.isEmpty(path) || !path.startsWith("/")) {
            throw new HandlerException(Consts.TAG + "Extract the default group failed, the path must be start with '/' and contain more than 2 '/'!");
        }

        try {
            String defaultGroup = path.substring(1, path.indexOf("/", 1));
            if (TextUtils.isEmpty(defaultGroup)) {
                throw new HandlerException(Consts.TAG + "Extract the default group failed! There's nothing between 2 '/'!");
            } else {
                return defaultGroup;
            }
        } catch (Exception e) {
            logger.warning(Consts.TAG, "Failed to extract default group! " + e.getMessage());
            return null;
        }
    }

在上面的build方法中,会先判断有没有设置了PathReplaceService,如果有设置了就会调用PathReplaceService.forString方法返回新的path,如果没有设置则会使用原来的path,这也就是路径替换的功能的实现

3.Postcard.navigation

navigation有多个重载的方法,而最终都会执行_ARouter的navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback)方法,就是通过ARouter的navigation调用_ARouter的navigation方法。

    public Object navigation(Context mContext, Postcard postcard, int requestCode, NavigationCallback callback) {
        return _ARouter.getInstance().navigation(mContext, postcard, requestCode, callback);
    }

而_ARouter的navigation方法实现如下:

    protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
        PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);
        if (null != pretreatmentService && !pretreatmentService.onPretreatment(context, postcard)) {
            // Pretreatment failed, navigation canceled.
            return null;
        }

        try {
            // 在这里最终会把每个group下的RouteMeta保存在Warehouse.routes中
            LogisticsCenter.completion(postcard);
        } catch (NoRouteFoundException ex) {
            logger.warning(Consts.TAG, ex.getMessage());

            if (debuggable()) {
                // Show friendly tips for user.
                runInMainThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(mContext, "There's no route matched!\n" +
                                " Path = [" + postcard.getPath() + "]\n" +
                                " Group = [" + postcard.getGroup() + "]", Toast.LENGTH_LONG).show();
                    }
                });
            }

            if (null != callback) {
                callback.onLost(postcard);
            } else {
                // No callback for this invoke, then we use the global degrade service.
                DegradeService degradeService = ARouter.getInstance().navigation(DegradeService.class);
                if (null != degradeService) {
                    degradeService.onLost(context, postcard);
                }
            }

            return null;
        }

        if (null != callback) {
            callback.onFound(postcard);
        }

        if (!postcard.isGreenChannel()) {   // It must be run in async thread, maybe interceptor cost too mush time made ANR.
            interceptorService.doInterceptions(postcard, new InterceptorCallback() {
                /**
                 * Continue process
                 *
                 * @param postcard route meta
                 */
                @Override
                public void onContinue(Postcard postcard) {
                    _navigation(context, postcard, requestCode, callback);
                }

                /**
                 * Interrupt process, pipeline will be destory when this method called.
                 *
                 * @param exception Reson of interrupt.
                 */
                @Override
                public void onInterrupt(Throwable exception) {
                    if (null != callback) {
                        callback.onInterrupt(postcard);
                    }

                    logger.info(Consts.TAG, "Navigation failed, termination by interceptor : " + exception.getMessage());
                }
            });
        } else {
            return _navigation(context, postcard, requestCode, callback);
        }

        return null;
    }
public synchronized static void completion(Postcard postcard) {
    //第一次进来是拿不到RouteMeta信息的,因为routes是空的
    RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
    if (null == routeMeta) {
        //我们传过来的postcard的group是arouter、path是/arouter/service/interceptor
        //我们在groupIndex中找对应的groupMeta,其实看到这的时候,我们默认是没有root为arouter的组,只能去arouter默认提供的root中找
        Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());  // Load route meta.
        if (null == groupMeta) {
        } else {
            try {
                //反射拿到ARouter$$Group$$arouter
                IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();
                //所以最终把InterceptorServiceImpl放到了Warehouse.routes中
                iGroupInstance.loadInto(Warehouse.routes);
                //用完groupsIndex对应的IRouteGroup信息后,从map中移除掉,下次就直接从routes中去拿了
                Warehouse.groupsIndex.remove(postcard.getGroup());

            } catch (Exception e) {
                throw new HandlerException(TAG + "Fatal exception when loading group meta. [" + e.getMessage() + "]");
            }
            //继续走一遍completion,下次会走下面的else
            completion(postcard);
        }
    } else {
        //对postCard属性赋值
        postcard.setDestination(routeMeta.getDestination());
        postcard.setType(routeMeta.getType());
        postcard.setPriority(routeMeta.getPriority());
        postcard.setExtra(routeMeta.getExtra());

        Uri rawUri = postcard.getUri();
        //默认uri为空
        if (null != rawUri) {  
            Map<String, String> resultMap = TextUtils.splitQueryParameters(rawUri);
            Map<String, Integer> paramsType = routeMeta.getParamsType();

            if (MapUtils.isNotEmpty(paramsType)) {
                for (Map.Entry<String, Integer> params : paramsType.entrySet()) {
                    setValue(postcard,
                            params.getValue(),
                            params.getKey(),
                            resultMap.get(params.getKey()));
                }

                // Save params name which need auto inject.
                postcard.getExtras().putStringArray(ARouter.AUTO_INJECT, paramsType.keySet().toArray(new String[]{}));
            }

            // Save raw uri
            postcard.withString(ARouter.RAW_URI, rawUri.toString());
        }

        switch (routeMeta.getType()) {
            //由于InterceptorServiceImpl是provider类型的
            case PROVIDER:
                Class<? extends IProvider> providerMeta = (Class<? extends IProvider>) routeMeta.getDestination();
                //拿对应的provider
                IProvider instance = Warehouse.providers.get(providerMeta);
                if (null == instance) {
                    IProvider provider;
                    try {
                        //反射创建InterceptorServiceImpl
                        provider = providerMeta.getConstructor().newInstance();
                        //调用InterceptorServiceImpl的init方法
                        provider.init(mContext);
                        Warehouse.providers.put(providerMeta, provider);
                        instance = provider;
                    } catch (Exception e) {
                        throw new HandlerException("Init provider failed! " + e.getMessage());
                    }
                }
                //给postcard赋值
                postcard.setProvider(instance);
                postcard.greenChannel();
                break;
            case FRAGMENT:
                postcard.greenChannel();
            default:
                break;
        }
    }
}

这个过程需要注意,是对/arouter/service/interceptor这个interceptor服务转成RouteMeta,这个其实就是在alibaba:arouter-api这个库里生成的。


image.png
public class ARouter$$Group$$arouter implements IRouteGroup {
    public ARouter$$Group$$arouter() {
    }

    public void loadInto(Map<String, RouteMeta> atlas) {
        atlas.put("/arouter/service/autowired", RouteMeta.build(RouteType.PROVIDER, AutowiredServiceImpl.class, "/arouter/service/autowired", "arouter", (Map)null, -1, -2147483648));
        atlas.put("/arouter/service/interceptor", RouteMeta.build(RouteType.PROVIDER, InterceptorServiceImpl.class, "/arouter/service/interceptor", "arouter", (Map)null, -1, -2147483648));
    }
}

上面的这个过程,就是会从Warehouse.groupsIndex中把ARouter$$Group$$arouter加入到其中,然后在LogisticsCenter.completion方法中,取出这个分组,然后将arouter这个分组中的RouteMeta保存在Warehouse.routes中。这样就对interceptorService进行了初始化,其实就是InterceptorServiceImpl实例。
由于InterceptorServiceImpl的type是PROVIDER,所以在completion(postcard)方法中处理完第一个if分支之后,因为把分组内容从缓存中remove了,则会执行else分支,因为type是PROVIDER的原因,所以providerMeta是InterceptorServiceImpl类型的,然后去Warehouse.providers拿,此时是空的,所以通过反射创建InterceptorServiceImpl对象,创建完调用InterceptorServiceImpl调用init方法:

    @Override
    public void init(final Context context) {
        LogisticsCenter.executor.execute(new Runnable() {
            @Override
            public void run() {
                if (MapUtils.isNotEmpty(Warehouse.interceptorsIndex)) {
                    for (Map.Entry<Integer, Class<? extends IInterceptor>> entry : Warehouse.interceptorsIndex.entrySet()) {
                        Class<? extends IInterceptor> interceptorClass = entry.getValue();
                        try {
                            IInterceptor iInterceptor = interceptorClass.getConstructor().newInstance();
                            iInterceptor.init(context);
                            Warehouse.interceptors.add(iInterceptor);
                        } catch (Exception ex) {
                            throw new HandlerException(TAG + "ARouter init interceptor error! name = [" + interceptorClass.getName() + "], reason = [" + ex.getMessage() + "]");
                        }
                    }

                    interceptorHasInit = true;

                    logger.info(TAG, "ARouter interceptors init over.");

                    synchronized (interceptorInitLock) {
                        interceptorInitLock.notifyAll();
                    }
                }
            }
        });
    }

在这里就会初始化拦截器,接着就会继续回到_ARouter.navigation方法中调用LogisticsCenter.completion(postcard);初始化完成RouteMeta完成之后,继续执行interceptorService.doInterceptions的调用。如下:

    protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
        ...

        if (null != callback) {
            callback.onFound(postcard);
        }

        if (!postcard.isGreenChannel()) {   // It must be run in async thread, maybe interceptor cost too mush time made ANR.
            interceptorService.doInterceptions(postcard, new InterceptorCallback() {
                /**
                 * Continue process
                 *
                 * @param postcard route meta
                 */
                @Override
                public void onContinue(Postcard postcard) {
                    _navigation(context, postcard, requestCode, callback);
                }

                /**
                 * Interrupt process, pipeline will be destory when this method called.
                 *
                 * @param exception Reson of interrupt.
                 */
                @Override
                public void onInterrupt(Throwable exception) {
                    if (null != callback) {
                        callback.onInterrupt(postcard);
                    }

                    logger.info(Consts.TAG, "Navigation failed, termination by interceptor : " + exception.getMessage());
                }
            });
        } else {
            return _navigation(context, postcard, requestCode, callback);
        }

        return null;
    }

在这里就会调用InterceptorServiceImpl的doInterceptions,将要执行的RouteMeta进行分发判断是否执行拦截器。
看InterceptorServiceImpl.doInterceptions方法如下:

    @Override
    public void doInterceptions(final Postcard postcard, final InterceptorCallback callback) {
        if (null != Warehouse.interceptors && Warehouse.interceptors.size() > 0) {

            checkInterceptorsInitStatus();

            if (!interceptorHasInit) {
                callback.onInterrupt(new HandlerException("Interceptors initialization takes too much time."));
                return;
            }

            LogisticsCenter.executor.execute(new Runnable() {
                @Override
                public void run() {
                    CancelableCountDownLatch interceptorCounter = new CancelableCountDownLatch(Warehouse.interceptors.size());
                    try {
                        // 调用InterceptorServiceImpl的方法
                        _execute(0, interceptorCounter, postcard);
                        interceptorCounter.await(postcard.getTimeout(), TimeUnit.SECONDS);
                        if (interceptorCounter.getCount() > 0) {    // Cancel the navigation this time, if it hasn't return anythings.
                            callback.onInterrupt(new HandlerException("The interceptor processing timed out."));
                        } else if (null != postcard.getTag()) {    // Maybe some exception in the tag.
                            callback.onInterrupt(new HandlerException(postcard.getTag().toString()));
                        } else {
                            callback.onContinue(postcard);
                        }
                    } catch (Exception e) {
                        callback.onInterrupt(e);
                    }
                }
            });
        } else {
            callback.onContinue(postcard);
        }
    }
    private static void _execute(final int index, final CancelableCountDownLatch counter, final Postcard postcard) {
        if (index < Warehouse.interceptors.size()) {
            // 取出拦截器,并且调用拦截器的process方法
            IInterceptor iInterceptor = Warehouse.interceptors.get(index);
            iInterceptor.process(postcard, new InterceptorCallback() {
                @Override
                public void onContinue(Postcard postcard) {
                    // Last interceptor excute over with no exception.
                    counter.countDown();
                    _execute(index + 1, counter, postcard);  // When counter is down, it will be execute continue ,but index bigger than interceptors size, then U know.
                }

                @Override
                public void onInterrupt(Throwable exception) {
                    // Last interceptor excute over with fatal exception.

                    postcard.setTag(null == exception ? new HandlerException("No message.") : exception.getMessage());    // save the exception message for backup.
                    counter.cancel();
                    // Be attention, maybe the thread in callback has been changed,
                    // then the catch block(L207) will be invalid.
                    // The worst is the thread changed to main thread, then the app will be crash, if you throw this exception!
//                    if (!Looper.getMainLooper().equals(Looper.myLooper())) {    // You shouldn't throw the exception if the thread is main thread.
//                        throw new HandlerException(exception.getMessage());
//                    }
                }
            });
        }
    }

到这里,就可以看到对拦截器的触发。
拦截器其实是在ARouter.init()方法中调用_ARouter.afterInit()方法初始化了InterceptorService实例,然后在具体的执行路由的时候,就会调用InterceptorService实例触发拦截器的执行。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 一、ARouter ARouter使用的是APT(Annotation Processing Tool)注解处理器...
    zzq_nene阅读 2,164评论 0 0
  • 前言 随着项目业务逻辑和功能点日益递增, 逻辑的耦合程度也逐渐升高, 组件化技术可以很好的解决这个问题, 公司大佬...
    SharryChoo阅读 1,090评论 0 9
  • 今天我们接着来拆下ARouter的拦截器,这个是ARouter路由框架的第六篇分享了。在Android系统自带的s...
    juexingzhe阅读 17,703评论 2 19
  • 组件化被越来越多的Android项目采用,而作为组件化的基础——路由也是重中之重。本篇文章将详细的分析阿里巴巴开源...
    胡奚冰阅读 14,714评论 8 32
  • ARouter ARouter 是阿里云出品的Android中间件,负责处理盅跳转页面时的逻辑,简化和优化之前跳转...
    常强儿阅读 8,810评论 1 1