Log.d(Consts.TAG, “Filter " + classNames.size() + " classes by packageName <” + packageName + “>”);
return classNames;
}
这里的步骤比较简单,主要是如下的步骤:
-
通过
getSourcePaths
方法获取 dex 文件的 path 集合。 -
创建了一个
CountDownLatch
控制 dex 文件的并行处理,以加快速度。 -
遍历 path 列表,通过
DefaultPoolExecutor
对 path 并行处理。 -
加载 path 对应的 dex 文件,并对其中的 Entry 进行遍历,若发现了对应 package 下的 ClassName,将其加入结果集合。
-
所有 dex 处理完成后,返回结果。
关于 getSourcePaths
如何获取到的 dex 集合这里就不纠结了,因为我们的关注点不在这里。
初始化 Warehouse
Warehouse
实际上就是仓库的意思,它存放了 ARouter
自动生成的类(RouteRoot
、InterceptorGroup
、ProviderGroup
)的信息。
我们先看看 Warehouse
类究竟是怎样的:
class Warehouse {
// 保存 RouteGroup 对应的 class 以及 RouteMeta
static Map<String, Class<? extends IRouteGroup>> groupsIndex = new HashMap<>();
static Map<String, RouteMeta> routes = new HashMap<>();
// 保存 Provider 以及 RouteMeta
static Map<Class, IProvider> providers = new HashMap<>();
static Map<String, RouteMeta> providersIndex = new HashMap<>();
// 保存 Interceptor 对应的 class 以及 Inteceptor
static Map<Integer, Class<? extends IInterceptor>> interceptorsIndex = new UniqueKeyTreeMap<>(“More than one interceptors use same priority [%s]”);
static List interceptors = new ArrayList<>();
static void clear() {
routes.clear();
groupsIndex.clear();
providers.clear();
providersIndex.clear();
interceptors.clear();
interceptorsIndex.clear();
}
}
可以发现 Warehouse
就是一个纯粹用来存放信息的仓库类,它的数据的实际上是通过上面的几个自动生成的类在 loadInto
中对 Warehouse
主动填入数据实现的。
例如我们打开一个自动生成的 IRouteRoot
的实现类:
public class ARouter R o o t Root Roothomework implements IRouteRoot {
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
routes.put(“homework”, ARouter G r o u p Group Grouphomework.class);
}
}
可以看到,它在 groupsIndex
中对这个 RouteRoot
中的 IRouteGroup
进行了注册,也就是向 groupIndex
中注册了 Route Group 对应的 IRouteGroup
类。其他类也是一样,通过自动生成的代码将数据填入 Map
或 List
中。
可以发现,初始化过程主要完成了对自动生成的路由相关类 RouteRoot
、Interceptor
、ProviderGroup
的加载,对它们通过反射构造后将信息加载进了 Warehouse
类中。
Postcard 的创建
下面我们看看路由的跳转是如何实现的,我们先看到 ARouter.build
方法:
public Postcard build(String path) {
return _ARouter.getInstance().build(path);
}
它转调到了 _ARouter
的 build
方法:
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));
}
}
它首先通过 ARouter.navigation
获取到了 PathReplaceService
,它需要用户进行实现,若没有实现会返回 null
,若有实现则调用了它的 forString
方法传入了用户的 Route Path 进行路径的预处理。
最后转调到了 build(path, group)
,group
通过 extractGroup
得到:
private String extractGroup(String path) {
if (TextUtils.isEmpty(path) || !path.startsWith(“/”)) {
throw new HandlerException(Consts.TAG + “Extract the default group failed, the path must b