0%

02-组件化-第三节

一、ARouter 中 Path 和 Group 的关系

ARouter 里面这二者的关系比较简单,但是单纯看代码可能会比较蒙。其实很简单,用最简单的图示就能说清楚:

Group和Path的关系

  • Group:每个 Module 作为一个 Group 组

  • Path:每个 Module 中所有的 Activity (还可以拓展 Fragment)都放在 Path 里面

体现在代码里面就是生成的2种类(Group 和 Path):

1
2
3
4
5
6
7
8
public class ARouter$$Group$$personal implements ARouterGroup {
@Overrideag-0-1h3qlcbapag-1-1h3qlcbap
public Map<String, Class<? extends ARouterPath>> getGroupMap() {
Map<String, Class<? extends ARouterPath>> groupMap = new HashMap<>();
groupMap.put("personal", ARouter$$Path$$personal.class);
return groupMap;
}
}
1
2
3
4
5
6
7
8
9
public class ARouter$$Path$$personal implements ARouterPath {
@Override
public Map<String, RouterBean> getPathMap() {
Map<String, RouterBean> pathMap = new HashMap<>();
pathMap.put("/personal/Personal_Main2Activity", RouterBean.create();
pathMap.put("/personal/Personal_MainActivity", RouterBean.create());
return pathMap;
}
}

可以看到,在Group 类中 Map 是添加了 Path 的:

groupMap.put(“personal”, ARouter$$Path$$personal.class);

然后Path 里面的 pathMap 存放的key 是 path (如:”/personal/Personal_MainActivity”),value 是 Mainactivity.class (只不过被封装成 RouterBean 了)。

思考下,Path 类和 Group 类哪个先生成?肯定是 Path ,因为 Group 需要依赖 Path

使用JavaPoet 的时候,生成类型的时候,可以用 $T 来代替这个类型,再后面写上类型,类似于Android 中的 %1$s 的写法,比如构建 Map<String, Class<? extends ARouterPath>> groupMap = new HashMap<>(); 这行代码的时候:

1
2
3
4
5
6
7
8
9
methodBuidler.addStatement("$T<$T, $T> $N = new $T<>()",
ClassName.get(Map.class),
ClassName.get(String.class),

// Class<? extends ARouterPath> 难度
ParameterizedTypeName.get(ClassName.get(Class.class),
WildcardTypeName.subtypeOf(ClassName.get(pathType))), // ? extends ARouterPath
ProcessorConfig.GROUP_VAR1,
ClassName.get(HashMap.class));

看了代码,感觉太复杂的情况还不如直接不使用 Javapoet ,使用字符串去做还好点。

在自动生成 Group 和 Path 相关的类之后,我们可以使用如下方式去实现页面跳转了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public void jumpPersonal(View view) {
// 以前是这样跳转
/*Intent intent = new Intent(this, Personal_MainActivity.class);
intent.putExtra("name", "derry");
startActivity(intent);*/

// 现在是这样跳转 目前还要写这么多代码,是不是非常累

// TODO 最终的成效:用户 一行代码搞定,同时还可以传递参数,同时还可以懒加载

ARouter$$Group$$personal group$$personal = new ARouter$$Group$$personal();
Map<String, Class<? extends ARouterPath>> groupMap = group$$personal.getGroupMap();
Class<? extends ARouterPath> myClass = groupMap.get("personal");

try {
ARouter$$Path$$personal path = (ARouter$$Path$$personal) myClass.newInstance();
Map<String, RouterBean> pathMap = path.getPathMap();
RouterBean bean = pathMap.get("/personal/Personal_MainActivity");

if (bean != null) {
Intent intent = new Intent(this, bean.getMyClass());
startActivity(intent);
}

} catch (Exception e) {
e.printStackTrace();
}

}

我们先 new 出特定的 Group 对象,再获取其 Map 对象(这是缓存仓库,存储了其所有的 Path),然后根据 path 的name 获取到 Path 类的 Class 文件,之后使用这个 class 文件就能 newInstance 得出 path 对象,从path 对象中再得到其 Map 对象,最后,根据路径,从这个 Map 对象获得 RouterBean (也就是目标Activity 的Class )。

可见,到目前这一步还是很麻烦的,所以ARouter 再生成的代码上再一次生成代码,进一步封装。

注:

JavaPoet API:

https://github.com/square/javapoet

谢谢你的鼓励