一、interceptor
使用ARouter的攔截器的話,會生成對應(yīng)的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集合中,以攔截器的優(yōu)先級作為key,攔截器的class作為value。定義攔截器的時候,并不會封裝成RouteMeta對象進(jìn)行保存。
二、IProvider
在ARouter中,service其實也是繼承自IProvider的接口,比如PathReplaceService、PretreatmentService、SerializationService等,都是繼承了IProvider的。
而IProvider的實現(xiàn)類,會被包裝成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,根據(jù)不同的Service來實現(xiàn)不同的操作,比如PretreatmentService預(yù)處理服務(wù),在調(diào)用navigation的時候,就會先判斷預(yù)處理服務(wù)是否為空,并且是否返回了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是否需要被替換,則是通過在調(diào)用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的調(diào)用,則是在Postcard調(diào)用withObject的時候,獲取到該service,然后通過該service的object2Json和parseObject來對數(shù)據(jù)進(jìn)行處理。
parseObject的調(diào)用,其實就是在針對對應(yīng)的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中主動調(diào)用ARouter.getInstance().inject(this)
然后在這里會創(chuàng)建一個AutowiredService對象,用這個服務(wù)對象來處理ISyringe,其實就是對應(yīng)的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!");
}
}
}
在這里就會調(diào)用ISyringe的inject方法,就可以對對應(yīng)的Activity(其實就是傳給inject方法的參數(shù)target)屬性注入對應(yīng)的值,這些屬性不能是私有的,否則就不能直接通過對應(yīng)的Activity對象直接拿到屬性。
三、初始化流程解析攔截器和IProvider
1.ARouter.init(this);
在Application的onCreate方法中,調(diào)用進(jìn)行初始化,其內(nèi)部實現(xiàn)如下:
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中的各個集合的緩存內(nèi)容,將每個分組、Interceptor、Provider根據(jù)分組名和模塊名進(jìn)行文件的分別保存。
在初始化完成之后,就會調(diào)用_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方法中,會先判斷有沒有設(shè)置了PathReplaceService,如果有設(shè)置了就會調(diào)用PathReplaceService.forString方法返回新的path,如果沒有設(shè)置則會使用原來的path,這也就是路徑替換的功能的實現(xiàn)。
3.Postcard.navigation
navigation有多個重載的方法,而最終都會執(zhí)行_ARouter的navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback)方法,就是通過ARouter的navigation調(diào)用_ARouter的navigation方法。
public Object navigation(Context mContext, Postcard postcard, int requestCode, NavigationCallback callback) {
return _ARouter.getInstance().navigation(mContext, postcard, requestCode, callback);
}
而_ARouter的navigation方法實現(xiàn)如下:
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) {
//第一次進(jìn)來是拿不到RouteMeta信息的,因為routes是空的
RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
if (null == routeMeta) {
//我們傳過來的postcard的group是arouter、path是/arouter/service/interceptor
//我們在groupIndex中找對應(yīng)的groupMeta,其實看到這的時候,我們默認(rèn)是沒有root為arouter的組,只能去arouter默認(rèn)提供的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對應(yīng)的IRouteGroup信息后,從map中移除掉,下次就直接從routes中去拿了
Warehouse.groupsIndex.remove(postcard.getGroup());
} catch (Exception e) {
throw new HandlerException(TAG + "Fatal exception when loading group meta. [" + e.getMessage() + "]");
}
//繼續(xù)走一遍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();
//默認(rèn)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();
//拿對應(yīng)的provider
IProvider instance = Warehouse.providers.get(providerMeta);
if (null == instance) {
IProvider provider;
try {
//反射創(chuàng)建InterceptorServiceImpl
provider = providerMeta.getConstructor().newInstance();
//調(diào)用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服務(wù)轉(zhuǎn)成RouteMeta,這個其實就是在alibaba:arouter-api這個庫里生成的。

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進(jìn)行了初始化,其實就是InterceptorServiceImpl實例。
由于InterceptorServiceImpl的type是PROVIDER,所以在completion(postcard)方法中處理完第一個if分支之后,因為把分組內(nèi)容從緩存中remove了,則會執(zhí)行else分支,因為type是PROVIDER的原因,所以providerMeta是InterceptorServiceImpl類型的,然后去Warehouse.providers拿,此時是空的,所以通過反射創(chuàng)建InterceptorServiceImpl對象,創(chuàng)建完調(diào)用InterceptorServiceImpl調(diào)用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();
}
}
}
});
}
在這里就會初始化攔截器,接著就會繼續(xù)回到_ARouter.navigation方法中調(diào)用LogisticsCenter.completion(postcard);初始化完成RouteMeta完成之后,繼續(xù)執(zhí)行interceptorService.doInterceptions的調(diào)用。如下:
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;
}
在這里就會調(diào)用InterceptorServiceImpl的doInterceptions,將要執(zhí)行的RouteMeta進(jìn)行分發(fā)判斷是否執(zhí)行攔截器。
看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 {
// 調(diào)用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()) {
// 取出攔截器,并且調(diào)用攔截器的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());
// }
}
});
}
}
到這里,就可以看到對攔截器的觸發(fā)。
攔截器其實是在ARouter.init()方法中調(diào)用_ARouter.afterInit()方法初始化了InterceptorService實例,然后在具體的執(zhí)行路由的時候,就會調(diào)用InterceptorService實例觸發(fā)攔截器的執(zhí)行。