本系列文章主要分析 ARouter 框架的架构和原理。
这是阿里 ARouter 开源库的地址,大家可以直接访问
https://github.com/alibaba/ARouter
本篇博文主要分析 arouter-api 模块,该模块涉及到 ARouter 一些核心逻辑:初始化,跳转,拦截,服务等,下面的几篇文章就要从这几个方向来分析;
在阅读过程中,涉及到方法跳转的时候,注释上有 -->
的标志,这样的好处是,以类为单位,一次性分析其所有的方法!
1 开篇 这篇文章分析下 ARouter 的 Service 和 Interceptor,二者有如下的区别:
1.1 实现接口不同
Service 直接或者间接的实现了 IProvider 接口:
1 2 3 public interface IProvider { void init (Context context) ; }
Interceptor 直接或者间接的实现了 IInterceptor 接口:
1 2 3 public interface IInterceptor extends IProvider { void process (Postcard postcard, InterceptorCallback callback) ; }
1.2 注解不同
1 2 3 @Route (path = "/yourservicegroupname/single" )public class SingleService implements IProvider {}
Interceptor 使用 @Interceptor 注解处理:
1 2 3 @Interceptor (priority = 7 )public class Test1Interceptor implements IInterceptor {}
1.3 逻辑处理不同
拦截器会在 ARouter 初始化 init 的时候异步初始化,如果第一次路由的时候拦截器还没有初始化结束,路由会等待,直到初始化完成。- 这个下面可以看到,内部有一个同步锁来控制;
服务没有该限制,某一服务可能在 App 整个生命周期中都不会用到,所以服务只有被调用的时候才会触发初始化操作;
1 服务 Service 1.1 服务统一接口 ARouter 已经帮我们提供了一些 Service 统一接口,对于对内对外提供特定的功能模版:
1 2 3 4 5 6 7 -rwxr-xr-x 1 lishuaiqi820 235765416 468 May 8 20:46 AutowiredService.java -rwxr-xr-x 1 lishuaiqi820 235765416 424 May 8 20:46 ClassLoaderService.java -rwxr-xr-x 1 lishuaiqi820 235765416 590 May 8 20:46 DegradeService.java -rwxr-xr-x 1 lishuaiqi820 235765416 575 May 8 20:46 InterceptorService.java -rwxr-xr-x 1 lishuaiqi820 235765416 555 May 8 20:46 PathReplaceService.java -rwxr-xr-x 1 lishuaiqi820 235765416 656 May 8 20:46 PretreatmentService.java -rwxr-xr-x 1 lishuaiqi820 235765416 974 May 8 20:46 SerializationService.java
AutowiredService :用于处理 Autowired 注解的变量的 Service,ARouter 内置了一个 AutowiredServiceImpl 实现了 AutowiredService,我们在分析 inject 的时候,再讲;
ClassLoaderService :针对于 installrun 的 Service;
DegradeService :用于在跳转不成功的情况下,做降级处理;
InterceptorService :用于处理 Interceptor 的 Service,ARouter 内置了一个 InterceptorServiceImpl 实现了 InterceptorService,用于初始化所有的 Interceptor 和处理拦截,我们下面分析;
PathReplaceService :用于对路由的 path 做预处理;
PretreatmentService ;用于在跳转之前做预处理操作;
SerializationService :用于序列化 Object 对象,和 Autowired 注解配合使用,我们在分析 inject 的时候,再讲;
1.2 获取服务 ARouter 是通过路由跳转的方式获取服务的,我们来回顾 init 的流程:
1 PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
1 interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor" ).navigation();
之前在分析 init 的过程中,我们又遇到好几个获取 Service 的地方,上面是举了其中几个栗子!
1 serializationService = ARouter.getInstance().navigation(SerializationService.class);
上面的代码是在处理 @Autowired 注解的时候,也就是 arouter complier 编译的时候处理的,用于传递自定义的对象;
1.3 获取流程分析 通过上面可以知道,获取一个 Service 的方法有两种:
1 2 3 ARouter.getInstance().navigation(xxxx.class); ARouter.getInstance().build(path).navigation();
下面我们会分析下这两种方式的流程!
有些代码在前面的路由处理过程中分析了,这里不会再重复分析。
1.3.1 navigation(className.class) 第一种方式是传入 Service 的父类,我们回顾下调用链 :
1 2 3 4 5 6 ARouter.getInstance().navigation(service.class); _ARouter.getInstance().navigation(service); Postcard postcard = LogisticsCenter.buildProvider(service.getName()); Postcard postcard = Warehouse.providersIndex.get(serviceName); LogisticsCenter.completion(postcard); _ARouter.getInstance()._navigation(...);
上面这部分的调用过程实际上,我们在路由初始化的时候见到过!
这里我们只看核心的逻辑,省略掉一些奇葩的
1.3.1.1 _ARouter.navigation 我回顾下 _ARouter.navigation 方法;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 protected <T> T navigation (Class<? extends T> service) { try { Postcard postcard = LogisticsCenter.buildProvider(service.getName()); if (null == postcard) { postcard = LogisticsCenter.buildProvider(service.getSimpleName()); } if (null == postcard) { return null ; } LogisticsCenter.completion(postcard); return (T) postcard.getProvider(); } catch (NoRouteFoundException ex) { logger.warning(Consts.TAG, ex.getMessage()); return null ; } }
这里的核心处理:
LogisticsCenter.buildProvider
LogisticsCenter.completion
1.3.1.2 LogisticsCenter.buildProvider 1 2 3 4 5 6 7 8 9 10 11 public static Postcard buildProvider (String serviceName) { RouteMeta meta = Warehouse.providersIndex.get(serviceName); if (null == meta) { return null ; } else { return new Postcard(meta.getPath(), meta.getGroup()); } }
这里的 Warehouse.providersIndex 保存的是如下的数据:
1 2 providers.put("com.alibaba.android.arouter.facade.service.SerializationService" , RouteMeta.build(RouteType.PROVIDER, MySerializationService.class, "/coolqiService/MySerializationService" , "coolqiService" , null , -1 , -2147483648 ));
1.3.1.3 LogisticsCenter.completion 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 public synchronized static void completion (Postcard postcard) { if (null == postcard) { throw new NoRouteFoundException(TAG + "No postcard!" ); } RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath()); if (null == routeMeta) { Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup()); if (null == groupMeta) { throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]" ); } else { try { if (ARouter.debuggable()) { logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] starts loading, trigger by [%s]" , postcard.getGroup(), postcard.getPath())); } IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance(); iGroupInstance.loadInto(Warehouse.routes); Warehouse.groupsIndex.remove(postcard.getGroup()); if (ARouter.debuggable()) { logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] has already been loaded, trigger by [%s]" , postcard.getGroup(), postcard.getPath())); } } catch (Exception e) { throw new HandlerException(TAG + "Fatal exception when loading group meta. [" + e.getMessage() + "]" ); } completion(postcard); } } else { postcard.setDestination(routeMeta.getDestination()); postcard.setType(routeMeta.getType()); postcard.setPriority(routeMeta.getPriority()); postcard.setExtra(routeMeta.getExtra()); Uri rawUri = postcard.getUri(); 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())); } postcard.getExtras().putStringArray(ARouter.AUTO_INJECT, paramsType.keySet().toArray(new String[]{})); } postcard.withString(ARouter.RAW_URI, rawUri.toString()); } switch (routeMeta.getType()) { case PROVIDER: Class<? extends IProvider> providerMeta = (Class<? extends IProvider>) routeMeta.getDestination(); IProvider instance = Warehouse.providers.get(providerMeta); if (null == instance) { IProvider provider; try { provider = providerMeta.getConstructor().newInstance(); provider.init(mContext); Warehouse.providers.put(providerMeta, provider); instance = provider; } catch (Exception e) { throw new HandlerException("Init provider failed! " + e.getMessage()); } } postcard.setProvider(instance); postcard.greenChannel(); break ; case FRAGMENT: postcard.greenChannel(); default : break ; } } }
这里有所谓的 “按组加载”
可以看到,最后获取了 Service,并调用了其 init 方法;
最后将获得的 Service 保存到了 Postcard 中;
1.3.2 build(path).navigation() 第二种方式是通过 path 来查找 Service,我们回顾下调用链 :
1 2 3 4 5 6 7 ARouter.getInstance().build(path).navigation() Postcard postcard = _ARouter.getInstance().build(path) Object object = Postcard.navigation(); Object object = ARouter.getInstance().navigation(context, this , -1 , callback) Object object = _ARouter.getInstance().navigation(mContext, postcard, requestCode, callback) LogisticsCenter.completion(postcard); Object object = _ARouter.getInstance()._navigation(...);
上面这部分的调用过程实际上,我们在路由初始化的时候见到过!
这里我们只看核心的逻辑,省略掉一些非核心的代码;
1.3.2.1 _ARouter.navigation 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 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)) { return null ; } try { LogisticsCenter.completion(postcard); } catch (NoRouteFoundException ex) { logger.warning(Consts.TAG, ex.getMessage()); if (debuggable()) { 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 { 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()) { interceptorService.doInterceptions(postcard, new InterceptorCallback() { @Override public void onContinue (Postcard postcard) { _navigation(context, postcard, requestCode, callback); } @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 ; }
1.3.2.4 _ARouter._navigation 最终处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private Object _navigation (final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) { final Context currentContext = null == context ? mContext : context; switch (postcard.getType()) { case ACTIVITY: ... ... ... break ; case PROVIDER: return postcard.getProvider(); case BOARDCAST: case CONTENT_PROVIDER: case FRAGMENT: ... ... ... case METHOD: case SERVICE: default : return null ; } return null ; }
就这样,我们获得了 Service 对象!
1.4 内置服务 我们来看看内置服务接口!
对与 AutowiredService,InterceptorService,SerializationService 我们后面会分析,这里就不重点分析了,累!
1.4.1 DegradeService 降级服务,当跳转失败后,可以在这里做处理:
1 2 3 4 public interface DegradeService extends IProvider { void onLost (Context context, Postcard postcard) ; }
1.4.2 PathReplaceService 路径 path 替换服务,我们可以在启动跳转之前,对 path 进行拦截,替换新的 path:
1 2 3 4 public interface PathReplaceService extends IProvider { String forString (String path) ; Uri forUri (Uri uri) ; }
可以针对 path 和 uri 两种方式!
1.4.3 PretreatmentService 跳转预处理服务,我们可以在启动跳转之前,针对跳转路由数据做预处理:
1 2 3 4 public interface PathReplaceService extends IProvider { String forString (String path) ; Uri forUri (Uri uri) ; }
可以针对 path 和 uri 两种方式!
2 拦截器 Interceptor 2.1 InterceptorServiceImpl - 统一管理拦截器 在 ARouter 框架里面,有一个 InterceptorServiceImpl 服务,用于统一管理 Interceptor:
1 2 3 static void afterInit () { interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor" ).navigation(); }
这里我们就不多说了,这个是获取拦截器管理服务的方式,流程上面分析了;
2.2 初始化 Interceptor Interceptor 的初始化由 InterceptorServiceImpl 完成,
核心的逻辑在 LogisticsCenter.completion 中!
2.2.1 LogisticsCenter.completion 这里我们省略掉无关的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public synchronized static void completion (Postcard postcard) { if (null == postcard) { throw new NoRouteFoundException(TAG + "No postcard!" ); } RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath()); if (null == routeMeta) { ... ... ... } else { ... ... ... switch (routeMeta.getType()) { case PROVIDER: Class<? extends IProvider> providerMeta = (Class<? extends IProvider>) routeMeta.getDestination(); IProvider instance = Warehouse.providers.get(providerMeta); if (null == instance) { IProvider provider; try { provider = providerMeta.getConstructor().newInstance(); provider.init(mContext); Warehouse.providers.put(providerMeta, provider); instance = provider; } catch (Exception e) { throw new HandlerException("Init provider failed! " + e.getMessage()); } } postcard.setProvider(instance); postcard.greenChannel(); break ; case FRAGMENT: postcard.greenChannel(); default : break ; } } }
回顾 :
我们知道在路由初始化的过程中,afterInit 会获得 InterceptorServiceImpl 方法并执行其 init 的初始化操作!
2.2.2 InterceptorServiceImpl.init 在 InterceptorServiceImpl 的 init 方法中,会获取所有的 Interceptor,并对其做初始化操作;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 @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(); } } } }); }
这里是在由线程池管理的字现场中执行 init 操作!
注意,这里有一个同步锁,如果在路由的时候,发现 interceptorHasInit 为 false,那么会调用 interceptorInitLock.wait 进入阻塞状态,等待初始化完成,被 notifyAll 唤醒!
2.3 拦截操作 我们来看看拦截操作是如何做的,核心代码在 _ARouter.navigation 中:
2.3.1 _ARouter.navigation 我们只关注核心的逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 protected Object navigation (final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) { ... ... ... if (null != callback) { callback.onFound(postcard); } if (!postcard.isGreenChannel()) { interceptorService.doInterceptions(postcard, new InterceptorCallback() { @Override public void onContinue (Postcard postcard) { _navigation(context, postcard, requestCode, callback); } @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 ; }
我们看到,这里传入了一个拦截结果回调:
2.3.1.1 InterceptorCallback 位于 callback 包下:
1 2 3 4 public interface InterceptorCallback { void onContinue (Postcard postcard) ; void onInterrupt (Throwable exception) ; }
2.3.2 InterceptorServiceImpl.doInterceptions 当我们路由跳转时,如果指定了 Interceptor,那么就要执行拦截操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 @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 { _excute(0 , interceptorCounter, postcard); interceptorCounter.await(postcard.getTimeout(), TimeUnit.SECONDS); if (interceptorCounter.getCount() > 0 ) { callback.onInterrupt(new HandlerException("The interceptor processing timed out." )); } else if (null != postcard.getTag()) { callback.onInterrupt(new HandlerException(postcard.getTag().toString())); } else { callback.onContinue(postcard); } } catch (Exception e) { callback.onInterrupt(e); } } }); } else { callback.onContinue(postcard); } }
这里其实可以看出,拦截器使用了责任链模式!
这里有一个新的类型:CancelableCountDownLatch,其实就是一个 CountDownLatch,代码很简单,不多说了!
2.3.2.1 checkInterceptorsInitStatus 判断是否初始化完成:
1 2 3 4 5 6 7 8 9 10 11 12 13 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() + "]" ); } } } }
interceptorInitLock 是 InterceptorServiceImpl 内部的一个锁对象;
2.3.2.2 _excute index 的值为 0,开始执行拦截:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 private static void _excute (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) { counter.countDown(); _excute(index + 1 , counter, postcard); } @Override public void onInterrupt (Throwable exception) { postcard.setTag(null == exception ? new HandlerException("No message." ) : exception.getMessage()); counter.cancel(); } }); } }
整个过程很简单,不多说了。
3 线程池 刚刚我们有看到,拦截器的初始化和拦截都是在子线程中做的,ARouter 通过内部的一个线程池来管理:
1 2 DefaultPoolExecutor.java DefaultThreadFactory.java
3.1 线程池初始化 1 2 3 4 5 6 7 8 9 final class _ARouter { static ILogger logger = new DefaultLogger(Consts.TAG); private volatile static boolean monitorMode = false ; private volatile static boolean debuggable = false ; private volatile static boolean autoInject = false ; private volatile static _ARouter instance = null ; private volatile static boolean hasInit = false ; private volatile static ThreadPoolExecutor executor = DefaultPoolExecutor.getInstance();
然后再初始化 LogisticsCenter 的时候传递给了 LogisticsCenter;
3.2 DefaultPoolExecutor 我们来看下线程池的构造,这里要重点看看线程池的核心参数:
3.2.1 getInstance 单例模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public static DefaultPoolExecutor getInstance () { if (null == instance) { synchronized (DefaultPoolExecutor.class) { if (null == instance) { instance = new DefaultPoolExecutor( INIT_THREAD_COUNT, MAX_THREAD_COUNT, SURPLUS_THREAD_LIFE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(64 ), new DefaultThreadFactory()); } } } return instance; }
3.2.2 new DefaultPoolExecutor 我们来研究下 DefaultPoolExecutor 的一些核心参数:
1 2 3 4 5 6 7 8 9 private DefaultPoolExecutor (int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { super (corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, new RejectedExecutionHandler() { @Override public void rejectedExecution (Runnable r, ThreadPoolExecutor executor) { ARouter.logger.error(Consts.TAG, "Task rejected, too many task!" ); } }); }
这里涉及到了 DefaultPoolExecutor 内部的常量:
1 2 3 4 private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int INIT_THREAD_COUNT = CPU_COUNT + 1 ; private static final int MAX_THREAD_COUNT = INIT_THREAD_COUNT; private static final long SURPLUS_THREAD_LIFE = 30L ;
可以看到,线程池的参数如下:
corePoolSize:核心线程数是可用的处理器数量 + 1;
maximumPoolSize:最大线程数是可用的处理器数量;
keepAliveTime:空闲线程存活时间:30s;
workQueue:阻塞队列是 ArrayBlockingQueue,数组实现的阻塞队列,有界 64;
threadFactory:线程工厂类,自定义的 DefaultThreadFactory 类;
RejectedExecutionHandler:线程池在无法处理添加的 runnnable 时的处理机制,这里是自定义了一个 RejectedExecutionHandler,只是打印了一个 Log;
3.3 DefaultThreadFactory ARouter 内部自定义的线程工厂类,DefaultThreadFactory 需要实现 ThreadFactory 接口;
1 2 3 4 5 6 7 public DefaultThreadFactory () { SecurityManager s = System.getSecurityManager(); group = (s != null ) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = "ARouter task pool No." + poolNumber.getAndIncrement() + ", thread No." ; }
我们来看看 newThread 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public Thread newThread (@NonNull Runnable runnable) { String threadName = namePrefix + threadNumber.getAndIncrement(); ARouter.logger.info(Consts.TAG, "Thread production, name is [" + threadName + "]" ); Thread thread = new Thread(group, runnable, threadName, 0 ); if (thread.isDaemon()) { thread.setDaemon(false ); } if (thread.getPriority() != Thread.NORM_PRIORITY) { thread.setPriority(Thread.NORM_PRIORITY); } thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException (Thread thread, Throwable ex) { ARouter.logger.info(Consts.TAG, "Running task appeared exception! Thread [" + thread.getName() + "], because [" + ex.getMessage() + "]" ); } }); return thread; }
不多说了!
4 总结 本篇文章分析了 ARouter 的服务和拦截器的相关机制
拦截器的初始化和拦截操作都是在子线程中处理的,拦截器使用了责任链模式;
子线程通过线程池管理,采用了单例模式;
拦截器是使用了责任链模式,通过它使用 CountDownLatch 来实现了路由等待的操作;
但是遗留了几个问题:
AutowiredService 和 AutowiredServiceImpl 是如何工作的;
ClassLoaderService 是如何工作的;
我们下次再说~~~