// zip 结尾通过 DexFile.loadDex 进行加载
dexfile = DexFile.loadDex(path, path + “.tmp”, 0);
} else {
// 否则通过 new DexFile 加载
dexfile = new DexFile(path);
}
// 遍历 dex 中的 Entry
Enumeration dexEntries = dexfile.entries();
while (dexEntries.hasMoreElements()) {
// 如果是对应的 package 下的类,则添加其 className
String className = dexEntries.nextElement();
if (className.startsWith(packageName)) {
classNames.add(className);
}
}
} catch (Throwable ignore) {
Log.e(“ARouter”, “Scan map file in dex files made error.”, ignore);
} finally {
if (null != dexfile) {
try {
dexfile.close();
} catch (Throwable ignore) {
}
}
parserCtl.countDown();
}
}
});
}
// 所有 path 处理完成后,继续向下走
parserCtl.await();
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 Gro