本篇文章主要讲解了 ARouter 框架的源码分析,包括其初始化过程、核心方法等。
初始化
在使用ARouter的时候我们都会先进行初始化:
ARouter.init(this);
我们看下 init() 源码:
public static void init(Application application) {
// 检查 ARouter 是否已经初始化,避免重复初始化
if (!hasInit) {
// 获取 logger,并记录初始化开始的日志
logger = _ARouter.logger;
_ARouter.logger.info(Consts.TAG, "ARouter init start.");
// 执行 ARouter 的初始化方法,并将初始化结果赋值给 hasInit
hasInit = _ARouter.init(application);
// 如果初始化成功,执行后续的初始化步骤
if (hasInit) {
_ARouter.afterInit();
}
// 记录初始化完成的日志
_ARouter.logger.info(Consts.TAG, "ARouter init over.");
}
}
真正调用的还是里面的 _ARouter.init():
protected static synchronized boolean init(Application application) {
// 将传入的 Application 实例赋值给 mContext
mContext = application;
// 初始化 LogisticsCenter,通常是用来管理路由路径和目标组件的调度
LogisticsCenter.init(mContext, executor);
// 记录初始化成功的日志
logger.info(Consts.TAG, "ARouter init success!");
// 设置初始化标志,标记 ARouter 已初始化
hasInit = true;
// 创建一个 Handler 用于在主线程中处理消息
mHandler = new Handler(Looper.getMainLooper());
// 返回初始化成功
return true;
}
最终调用了LogisticsCenter的 init() 方法:
public synchronized static void init(Context context, ThreadPoolExecutor tpe) throws HandlerException {
// 保存上下文和线程池实例
mContext = context;
executor = tpe;
try {
// 记录初始化开始时间
long startInit = System.currentTimeMillis();
// 加载路由映射
loadRouterMap();
// 判断是否使用插件进行自动注册
if (registerByPlugin) {
logger.info(TAG, "Load router map by arouter-auto-register plugin.");
} else {
Set<String> routerMap;
// 如果是调试模式或者是新版本安装,则重新构建路由映射
if (ARouter.debuggable() || PackageUtils.isNewVersion(context)) {
logger.info(TAG, "Run with debug mode or new install, rebuild router map.");
// 获取路由类文件名(这些类是由 arouter-compiler 插件生成的)
routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);
// 如果有新的路由映射,保存到 SharedPreferences 中
if (!routerMap.isEmpty()) {
context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE)
.edit()
.putStringSet(AROUTER_SP_KEY_MAP, routerMap)
.apply();
}
// 更新应用版本信息
PackageUtils.updateVersion(context);
} else {
// 非调试模式且不是新版本时,从缓存中加载路由映射
logger.info(TAG, "Load router map from cache.");
routerMap = new HashSet<>(context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE)
.getStringSet(AROUTER_SP_KEY_MAP, new HashSet<String>()));
}
// 打印路由映射加载完成的日志
logger.info(TAG, "Find router map finished, map size = " + routerMap.size() + ", cost "
+ (System.currentTimeMillis() - startInit) + " ms.");
startInit = System.currentTimeMillis();
// 遍历所有路由映射,判断并加载对应的组件