组件化框架设计之阿里巴巴开源路由框架——ARouter原理分析

这个类是专门的Provider的索引的集合,所有的provider都被以全类名为索引放到一个map中。

package com.alibaba.android.arouter.routes;

//。。。import省略

/**

  • DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */

public class ARouter R o o t Root Rootmodlue_personal implements IRouteRoot {

@Override

public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {

routes.put(“Personal”, ARouter G r o u p Group GroupPersonal.class);

}

}

这个类是所有的group的信息收集,全部都以group的名字为key,以注解生成的不同的group的类的class对象为value放入到一个map中。

总共就生成这三种类型的类,当然,如果你有不同的分组还会生成其他的类,不过都是这三种里面的一种。

完成了这些注解信息的收集,下面就会去使用这些信息来完成我们的跨模块交互了。

初始化过程

========================================================================

使用ARouter必须先要进行初始化:

if (isDebug()) {

// These two lines must be written before init, otherwise these configurations will be invalid in the init process

ARouter.openLog(); // Print log

ARouter.openDebug(); // Turn on debugging mode (If you are running in InstantRun mode, you must turn on debug mode! Online version needs to be closed, otherwise there is a security risk)

}

ARouter.init(mApplication); // As early as possible, it is recommended to initialize in the Application

上面这段话就是去初始化Arouter,我们来看看init里面到底做了什么事。。。

/**

  • Init, it must be call before used router.

*/

public static void init(Application application) {

if (!hasInit) {

logger = _ARouter.logger;

_ARouter.logger.info(Consts.TAG, “ARouter init start.”);

hasInit = _ARouter.init(application);

if (hasInit) {

_ARouter.afterInit();

}

_ARouter.logger.info(Consts.TAG, “ARouter init over.”);

}

}

可以看到,这里使用了外观模式,最终调用都是在_ARouter这个类里面,跟进去:

protected static synchronized boolean init(Application application) {

mContext = application;

LogisticsCenter.init(mContext, executor);

logger.info(Consts.TAG, “ARouter init success!”);

hasInit = true;

// It’s not a good idea.

// if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) {

// application.registerActivityLifecycleCallbacks(new AutowiredLifecycleCallback());

// }

return true;

}

代码也很简单,核心就是LogisticsCenter.init这句话,跟进去看看,核心代码如下:

List classFileNames = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);

//

for (String className : classFileNames) {

if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_ROOT)) {

// This one of root elements, load root.

((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);

} else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_INTERCEPTORS)) {

// Load interceptorMeta

((IInterceptorGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.interceptorsIndex);

} else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_PROVIDERS)) {

// Load providerIndex

((IProviderGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.providersIndex);

}

}

我们可以看到,首先是去获取到所有的app里的由ARouter注解生成的类的类名,他们的统一特点就是在同一个包下,包名为:com.alibaba.android.arouter.routes

然后就是循环遍历这些类,也就是刚才我们说的那三种类。在这里,有一个Warehouse类,看下代码:

/**

  • Storage of route meta and other data.

  • @author zhilong Contact me.

  • @version 1.0

  • @since 2017/2/23 下午1:39

*/

class Warehouse {

// Cache route and metas

static Map<String, Class<? extends IRouteGroup>> groupsIndex = new HashMap<>();

static Map<String, RouteMeta> routes = new HashMap<>();

// Cache provider

static Map<Class, IProvider> providers = new HashMap<>();

static Map<String, RouteMeta> providersIndex = new HashMap<>();

// Cache interceptor

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();

}

}

很简单,定义了几个静态map,在初始化的时候来存放之前的注解生成的那些相关信息。初始化里面存的就是所有group索引的map,所有拦截器(本文不讲)索引的map,所有provider索引的map。至此,之前的那些注解类里面的信息都被存储起来了,这样后续在查找的时候就很方便可以找到对应的类,我们继续看初始化之后的afterInit方法:

static void afterInit() {

// Trigger interceptor init, use byName.

interceptorService = (InterceptorService) ARouter.getInstance().build(“/arouter/service/interceptor”).navigation();

}

我们跟踪之后,发现最终会调用LogisticsCenter中的completion方法:

/**

  • Completion the postcard by route metas

  • @param postcard Incomplete postcard, should completion by this method.

*/

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) { // 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

}

} else {

postcard.setDestination(routeMeta.getDestination());

postcard.setType(routeMeta.getType());

postcard.setPriority(routeMeta.getPriority());

postcard.setExtra(routeMeta.getExtra());

Uri rawUri = postcard.getUri();

if (null != rawUri) { // Try to set params into bundle.

Map<String, String> resultMap = TextUtils.splitQueryParameters(rawUri);

Map<String, Integer> paramsType = routeMeta.getParamsType();

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

给大家送上我成功跳槽复习中所整理的资料,由于文章篇幅有限,所以只是把题目列出来了

image

image

image

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
有帮助,可以添加V获取:vip204888 (备注Android)**
[外链图片转存中…(img-Jri536Lq-1712755484221)]

最后

给大家送上我成功跳槽复习中所整理的资料,由于文章篇幅有限,所以只是把题目列出来了

[外链图片转存中…(img-0n8IiXyq-1712755484221)]

[外链图片转存中…(img-TuAkQQBt-1712755484221)]

[外链图片转存中…(img-zi0sNoOS-1712755484221)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-PF0QeDV6-1712755484222)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值