ARouter讲解3_RouteProcessor,2024年最新如何在面试中逆袭

image-20210512234700592.png

详情

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (CollectionUtils.isNotEmpty(annotations)) {
// 获取所有被 Route 注解的类
Set<? extends Element> routeElements = roundEnv.getElementsAnnotatedWith(Route.class);
try {=
this.parseRoutes(routeElements);
} catch (Exception e) {
logger.error(e);
}
return true;
}

return false;
}

private void parseRoutes(Set<? extends Element> routeElements) throws IOException {
if (CollectionUtils.isNotEmpty(routeElements)) {

rootMap.clear();

TypeMirror type_Activity = elementUtils.getTypeElement(ACTIVITY).asType();
TypeMirror type_Service = elementUtils.getTypeElement(SERVICE).asType();
TypeMirror fragmentTm = elementUtils.getTypeElement(FRAGMENT).asType();
TypeMirror fragmentTmV4 = elementUtils.getTypeElement(Consts.FRAGMENT_V4).asType();

// Interface of ARouter
// com.alibaba.android.arouter.facade.template.IRouteGroup
TypeElement type_IRouteGroup = elementUtils.getTypeElement(IROUTE_GROUP);
// com.alibaba.android.arouter.facade.template.IProviderGroup
TypeElement type_IProviderGroup = elementUtils.getTypeElement(IPROVIDER_GROUP);
ClassName routeMetaCn = ClassName.get(RouteMeta.class);
ClassName routeTypeCn = ClassName.get(RouteType.class);

/*
Build input type, format as :

*/
// 方法的参数类型
ParameterizedTypeName inputMapTypeOfRoot = ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(String.class),
ParameterizedTypeName.get(
ClassName.get(Class.class),
WildcardTypeName.subtypeOf(ClassName.get(type_IRouteGroup))
)
);

/*

*/
// 方法的参数类型
ParameterizedTypeName inputMapTypeOfGroup = ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(String.class),
ClassName.get(RouteMeta.class)
);

/*
Build input param name.
*/
// 方法的参数名
ParameterSpec rootParamSpec = ParameterSpec.builder(inputMapTypeOfRoot, “routes”).build();
ParameterSpec groupParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, “atlas”).build();
ParameterSpec providerParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, “providers”).build();

/*
Build method : ‘loadInto’
*/
// 构建一个方法 public void loadInto(Map<String, Class<? extends IRouteGroup>> routes)
MethodSpec.Builder loadIntoMethodOfRootBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO)
.addAnnotation(Override.class)
.addModifiers(PUBLIC)
.addParameter(rootParamSpec);

// Follow a sequence, find out metas of group first, generate java file, then statistics them as root.
// 遍历被Route注解的类
for (Element element : routeElements) {
TypeMirror tm = element.asType();
Route route = element.getAnnotation(Route.class);
RouteMeta routeMeta;

// 构建 RouteMeta
// 因为Activity 或者 Fragment 是可以传递参数的,getIntent()、getArguments(),就收集该类中被 Autowired 注解的字段
// Activity or Fragment
if (types.isSubtype(tm, type_Activity) || types.isSubtype(tm, fragmentTm) || types.isSubtype(tm, fragmentTmV4)) {
// 当前的类是 Activity 或 Fragment

// Get all fields annotation by @Autowired
// paramsType 与 injectConfig 用来生成文档的,不用关心
Map<String, Integer> paramsType = new HashMap<>();
Map<String, Autowired> injectConfig = new HashMap<>();
//收集类中的被Autowired注解的字段,但字段不能是IProvider类型
injectParamCollector(element, paramsType, injectConfig);

if (types.isSubtype(tm, type_Activity)) {
// Activity
routeMeta = new RouteMeta(route, element, RouteType.ACTIVITY, paramsType);
} else {
// Fragment
routeMeta = new RouteMeta(route, element, RouteType.parse(FRAGMENT), paramsType);
}

routeMeta.setInjectConfig(injectConfig);
} else if (types.isSubtype(tm, iProvider)) { // IProvider
routeMeta = new RouteMeta(route, element, RouteType.PROVIDER, null);
} else if (types.isSubtype(tm, type_Service)) { // Service
routeMeta = new RouteMeta(route, element, RouteType.parse(SERVICE), null);
} else {
throw new RuntimeException(“The @Route is marked on unsupported class, look at [” + tm.toString() + “].”);
}
// 收集具有相同的group的RouteMeta到 Map<String, Set>
categories(routeMeta);
}

// 生成 loadInto 方法
// public void loadInto(Map<Integer, Class<? extends IInterceptor>> interceptors)
MethodSpec.Builder loadIntoMethodOfProviderBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO)
.addAnnotation(Override.class)
.addModifiers(PUBLIC)
.addParameter(providerParamSpec);

// Start generate java source, structure is divided into upper and lower levels, used for demand initialization.
for (Map.Entry<String, Set> entry : groupMap.entrySet()) {

String groupName = entry.getKey();

//public void loadInto(Map<String, RouteMeta> atlas)
MethodSpec.Builder loadIntoMethodOfGroupBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO)
.addAnnotation(Override.class)
.addModifiers(PUBLIC)
.addParameter(groupParamSpec);

// Build group method body
Set groupData = entry.getValue();
for (RouteMeta routeMeta : groupData) {

// 这个ClassName就是被Route注解的类名
ClassName className = ClassName.get((TypeElement) routeMeta.getRawType());

//这是给 IProvider 的类型做了一次特殊服务

switch (routeMeta.getType()) {
case PROVIDER: // Need cache provider’s super class
// 注意 routeMeta 返回的是RouteType类型,比如 PROVIDER类型,就是说element是 IProvider 的子类。
// 获取这个TypeElement的直接父接口
// 比如我们一般定义XXXServiceImpl, XXXService ,然后XXXService接口继承自IProvider
List<? extends TypeMirror> interfaces = ((TypeElement) routeMeta.getRawType()).getInterfaces();
// 遍历这个父接口
for (TypeMirror tm : interfaces) {

if (types.isSameType(tm, iProvider)) { // Its implements iProvider interface himself.
// This interface extend the IProvider, so it can be used for mark provider
// 该element是 IProvider的直接子类

// 就会生成类似 providers.put(“com.alibaba.android.arouter.demo.module1.testservice.SingleService”,
// RouteMeta.build(RouteType.PROVIDER, SingleService.class, “/yourservicegroupname/single”, // “yourservicegroupname”, null, -1, -2147483648));
loadIntoMethodOfProviderBuilder.addStatement(
“providers.put($S, T . b u i l d ( T.build( T.build(T.” + routeMeta.getType() + ", $T.class, $S, $S, null, " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + “))”,
(routeMeta.getRawType()).toString(),
routeMetaCn,
routeTypeCn,
className,
routeMeta.getPath(),
routeMeta.getGroup());

} else if (types.isSubtype(tm, iProvider)) {

// This interface extend the IProvider, so it can be used for mark provider
// 类似这样 providers.put(“com.alibaba.android.arouter.demo.service.HelloService”,
// RouteMeta.build(RouteType.PROVIDER, HelloServiceImpl.class, “/yourservicegroupname/hello”,
// “yourservicegroupname”, null, -1, -2147483648));

loadIntoMethodOfProviderBuilder.addStatement(
“providers.put($S, T . b u i l d ( T.build( T.build(T.” + routeMeta.getType() + ", $T.class, $S, $S, null, " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + “))”,
tm.toString(), // So stupid, will duplicate only save class name.
routeMetaCn,
routeTypeCn,
className,
routeMeta.getPath(),
routeMeta.getGroup());
}
}
break;
default:
break;
}

// Make map body for paramsType
… 省略一部分代码…
}

// Generate groups
// ARouter G r o u p Group GroupgroupName
// 见图ARouter G r o u p Group GroupgroupName
String groupFileName = NAME_OF_GROUP + groupName;
JavaFile.builder(PACKAGE_OF_GENERATE_FILE, // com.alibaba.android.arouter.routes
TypeSpec.classBuilder(groupFileName)
.addJavadoc(WARNING_TIPS)
.addSuperinterface(ClassName.get(type_IRouteGroup))
.addModifiers(PUBLIC)
.addMethod(loadIntoMethodOfGroupBuilder.build())
.build()
).build().writeTo(mFiler);

// 组名和用组名生成的类缓存起来
rootMap.put(groupName, groupFileName);

}

if (MapUtils.isNotEmpty(rootMap)) {
// Generate root meta by group name, it must be generated before root, then I can find out the class of group.
for (Map.Entry<String, String> entry : rootMap.entrySet()) {
// 会生成类似这样的代码
// routes.put(“test”, ARouter G r o u p Group Grouptest.class);
// routes.put(“yourservicegroupname”, ARouter G r o u p Group Groupyourservicegroupname.class);
loadIntoMethodOfRootBuilder.addStatement(“routes.put($S, $T.class)”, entry.getKey(), ClassName.get(PACKAGE_OF_GENERATE_FILE, entry.getValue()));
}
}

// Output route doc
… 省略一部分代码…

// Write provider into disk
// ARouter P r o v i d e r s Providers ProvidersmoduleName
// 见图ARouter P r o v i d e r s Providers ProvidersmoduleName
String providerMapFileName = NAME_OF_PROVIDER + SEPARATOR + moduleName;
JavaFile.builder(PACKAGE_OF_GENERATE_FILE, // com.alibaba.android.arouter.routes
TypeSpec.classBuilder(providerMapFileName)
.addJavadoc(WARNING_TIPS)
.addSuperinterface(ClassName.get(type_IProviderGroup))

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

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

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

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

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

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

最后

给大家分享一份移动架构大纲,包含了移动架构师需要掌握的所有的技术体系,大家可以对比一下自己不足或者欠缺的地方有方向的去学习提升;

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

最后

给大家分享一份移动架构大纲,包含了移动架构师需要掌握的所有的技术体系,大家可以对比一下自己不足或者欠缺的地方有方向的去学习提升;

[外链图片转存中…(img-sCyWsGAY-1712781978516)]

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

  • 14
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值