ARouter源码分析—— 缓存与优化
Posted Alex_MaHao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARouter源码分析—— 缓存与优化相关的知识,希望对你有一定的参考价值。
Arouter
源码分析系列建议从最初开始阅读,全部文章请访问https://github.com/AlexMahao/ARouter
本篇博客意在记录ARouter
中的一些优秀策略。
辅助类加载机制
ARouter
在实现基本功能时,使用apt
在指定包名下生成了一些辅助类。辅助类的查询逻辑如下。
if (ARouter.debuggable() || PackageUtils.isNewVersion(context))
logger.info(TAG, "Run with debug mode or new install, rebuild router map.");
// These class was generated by arouter-compiler.
// 获取com.alibaba.android.arouter.routes的类列表,及Processor生成的辅助类
routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);
if (!routerMap.isEmpty())
// 保存路由表缓存
context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(AROUTER_SP_KEY_MAP, routerMap).apply();
// 修改新的路由表版本
PackageUtils.updateVersion(context); // Save new version name when router map update finishes.
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>()));
判断是否是debug
或者是否是新版本,其中一个成立,则重新查询并且遍历一下指定包下的所有辅助类。并且将辅助类的全路径保存到sp
中。
如果不满足条件,则从sp
中取。
尽可能减少耗时操作调用的次数。
路由的懒加载
对于一个大型app,存在的路由地址数量很大。而ARouter
的初始化方法都是在Application
中,那么势必导致app
加载时间过长。ARouter
通过分组懒加载的形式进行加载。
ARouter
在初始化的时候,只是加载了分组的类,即路由清单的class
,而没有加载详细的路由清单。
public class ARouter$$Root$$app implements IRouteRoot
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes)
routes.put("test", ARouter$$Group$$test.class);
routes.put("yourservicegroupname", ARouter$$Group$$yourservicegroupname.class);
然后当有路由地址跳转的时候,判断是否能查寻对应地址信息,如果没有,则会根据路由地址确定其分组,然后加载该组的路由清单。
public synchronized static void completion(Postcard postcard)
if (null == postcard)
throw new NoRouteFoundException(TAG + "No postcard!");
// 获取路由地址对应的信息
RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
// 如果为null可能是由于对应组别的路由清单没有加载
if (null == routeMeta) // Maybe its does't exist, or didn't load.
// 查询对应组的路由清单
Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup()); // Load route meta.
if (null == groupMeta)
// 如果不存在,则说明当前路径不存在
throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]");
else
// Load route and cache it into memory, then delete from metas.
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); // Reload
以上是关于ARouter源码分析—— 缓存与优化的主要内容,如果未能解决你的问题,请参考以下文章