Android 通过Router注解实现路由跳转
01.首先看ARouter注解实现方案
如下所示
1
2
3
4
5
6
7
8//首先通过注解添加下面代码
@Router(path = "/test/TestActivity")
public class TestActivity extends BaseActivity {
}
//跳转
ARouter.getsInstance().build("/test/TestActivity").navigation();
02.自定义Router注解
模仿ARouter案例,如下所示
- 这里看到Router注解里有path和group,这便是仿照ARouter对路由进行分组。因为当项目变得越来越大庞大的时候,为了便于管理和减小首次加载路由表过于耗时的问题,我们对所有的路由进行分组。在ARouter中会要求路由地址至少需要两级,如”/xx/xx”,一个模块下可以有多个分组。这里就将路由地址定为必须大于等于两级,其中第一级是group。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//@Retention用来修饰这是一个什么类型的注解。这里表示该注解是一个编译时注解。
@Retention(RetentionPolicy.CLASS)
//@Target用来表示这个注解可以使用在哪些地方。比如:类、方法、属性、接口等等。
//这里ElementType.TYPE 表示这个注解可以用来修饰:Class, interface or enum declaration。
@Target(ElementType.TYPE)
public @interface Router {
/**
* 路由的路径
* @return 字符串
*/
String path();
/**
* 将路由节点进行分组,可以实现动态加载
* @return 字符串,默认值是 ""
*/
String group() default "";
}思考一下,这里为何将地址设置为两级而不是一级呢?
03.查看生成的注解代码
在项目编译的时候,我们将会通过apt生成ARouter_Root_app文件和ARouter_Group_main等文件,EaseRouter_Root_app文件对应于app module,里面记录着本module下所有的分组信息,EaseRouter_Group_main文件分别记载着app module下每个分组的所有路由地址和ActivityClass映射信息。
本demo案例在编译的时候会生成类如下所示,先不要管这些类是怎么生成的,仔细看类的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class ARouter_Root_app implements IRouteRoot {
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
routes.put("main", ARouter_Group_main.class);
}
}
public class ARouter_Group_main implements IRouteGroup {
@Override
public void loadInto(Map<String, RouteMeta> atlas) {
atlas.put("/main/FiveActivity",RouteMeta.build(RouteMeta.Type.ACTIVITY,FiveActivity.class,"/main/FiveActivity","main"));
atlas.put("/main/SixActivity",RouteMeta.build(RouteMeta.Type.ACTIVITY,SixActivity.class,"/main/SixActivity","main"));
}
}分析上面代码原理
- 看到生成的类分别实现了IRouteRoot和IRouteGroup接口,并且实现了loadInto()方法,而loadInto方法通过传入一个特定类型的map就能把分组信息放入map里。这两个接口是干嘛的我们先搁置,继续往下看
- 如果我们在main_module中想启动app_module中的MainActivity类,首先,我们已知MainActivity类的路由地址是”/main/FiveActivity”,第一个”/main”代表分组名,那么我们岂不是可以像下面这样调用去得到MainActivity类文件,然后startActivity。这里的RouteMeta只是存有Activity class文件的封装类,先不用理会。
实现跳转简单代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/**
* 注解生成的代码,在build/generated/source/apt/debug/
* 模拟跳转到FiveActivity页面
*/
public void test() {
ARouter_Root_app rootApp = new ARouter_Root_app();
HashMap<String, Class<? extends IRouteGroup>> rootMap = new HashMap<>();
rootApp.loadInto(rootMap);
//得到/main分组
Class<? extends IRouteGroup> aClass = rootMap.get("main");
try {
HashMap<String, RouteMeta> groupMap = new HashMap<>();
aClass.newInstance().loadInto(groupMap);
//得到MainActivity
RouteMeta main = groupMap.get("/main/FiveActivity");
Class<?> clazz = main.getDestination();
Intent intent = new Intent(this, clazz);
startActivity(intent);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}只要有了这些实现了IRouteRoot和IRouteGroup的类文件,我们便能轻易的启动其他module的Activity了。其实这就是路由跳转的原理,这些类文件,我们可以约定好之后,在代码的编写过程中自己手动实现,也可以通过apt生成。作为一个框架,当然是自动解析Route注解然后生成这些类文件更好了。要想自动生成这些路由地址与Activity的映射关系,那么便要了解apt和javapoet了。