本系列文章主要分析 ARouter 框架的架构和原理。
这是阿里 ARouter 开源库的地址,大家可以直接访问
https://github.com/alibaba/ARouter
本篇博文主要分析 arouter-annotation 模块;
1 模块结构
下面我们来看看 arouter-annotation 的结构;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| src -> main -> java: |____com | |____alibaba | | |____android | | | |____arouter | | | | |____facade | | | | | |____enums | | | | | | |____RouteType.java | | | | | | |____TypeKind.java | | | | | |____annotation | | | | | | |____Interceptor.java | | | | | | |____Route.java | | | | | | |____Param.java | | | | | | |____Autowired.java | | | | | |____model | | | | | | |____TypeWrapper.java | | | | | | |____RouteMeta.java
|
一共有三个 package:
- enums:包含了一些枚举类:
- annotation:包含了一些注解;
- model:包含了一些跳转所需的数据;
2 源码分析
2.1 enums
这个 package 包含了一些枚举类:
2.1.1 RouteType
枚举类,每一个成员都用于保存 id 和 className 的映射!
className 包括 android 的 Activity,Service,ContentProvider,Fragment,以及 ARouter 自己的 IProvider 类型!
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public enum RouteType { ACTIVITY(0, "android.app.Activity" ), SERVICE(1, "android.app.Service"), PROVIDER(2, "com.alibaba.android.arouter.facade.template.IProvider"), CONTENT_PROVIDER(-1, "android.app.ContentProvider"), BOARDCAST(-1, ""), METHOD(-1, ""), FRAGMENT(-1, "android.app.Fragment"), UNKNOWN(-1, "Unknown route type");
int id; String className;
public int getId() { return id; }
public RouteType setId(int id) { this.id = id; return this; }
public String getClassName() { return className; }
public RouteType setClassName(String className) { this.className = className; return this; }
RouteType(int id, String className) { this.id = id; this.className = className; }
public static RouteType parse(String name) { for (RouteType routeType : RouteType.values()) { if (routeType.getClassName().equals(name)) { return routeType; } }
return UNKNOWN; } }
|
代码很简单,不多说。
它的作用是,我们可以通过 RouteType 判断判断 @Route 修饰的是类是那种类型;
2.1.2 TypeKind
枚举类,每一个枚举成员都用于表示一个类型,包括基本类型,可序列化类型,字符串,对象等等;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public enum TypeKind { BOOLEAN, BYTE, SHORT, INT, LONG, CHAR, FLOAT, DOUBLE,
STRING, SERIALIZABLE, PARCELABLE, OBJECT; }
|
它的作用是在设置跳转数据的时候,通过 TypeKind 来判断数据的类型,然后调用 Postcard.withXXX 方法,设置不同的类型;
2.2 annotation
这个 package 包含了一些注解类:
2.2.1 Route
用于注解 RouteType 指定的那些 type:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Target({ElementType.TYPE}) @Retention(RetentionPolicy.CLASS) public @interface Route { String path(); String group() default ""; String name() default ""; int extras() default Integer.MIN_VALUE; int priority() default -1; }
|
不多说了。
2.2.1.1 简单使用
1 2 3 4
| @Route(path = "/xxx/xxx") public class PretreatmentServiceImpl implements PretreatmentService { ... ... ... }
|
1 2 3 4
| @Route(path = "/test/activity") public class Test1Activity extends Activity { ... ... ... }
|
2.2.2 Autowired
用于修饰成员变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Target({ElementType.FIELD}) @Retention(RetentionPolicy.CLASS) public @interface Autowired {
String name() default "";
boolean required() default false;
String desc() default ""; }
|
2.2.2.1 简单使用
1 2 3 4
| @Route(path = "/xxx/xxx") public class PretreatmentServiceImpl implements PretreatmentService { ... ... ... }
|
1 2 3 4
| @Route(path = "/test/activity") public class Test1Activity extends Activity { ... ... ... }
|
2.2.3 Interceptor
用于注解拦截器:
1 2 3 4 5 6 7 8 9
| @Target({ElementType.TYPE}) @Retention(RetentionPolicy.CLASS) public @interface Interceptor { int priority();
String name() default "Default"; }
|
2.2.3.1 简单使用
1 2 3 4
| @Interceptor(priority = 8, name = "测试用拦截器") public class TestInterceptor implements IInterceptor { ... ... ... }
|
2.2.4 Param(DEPRECATED)
这个注解也是用来修饰成员变量的,但是不推荐使用了,请使用 Autowired!
1 2 3 4 5 6 7 8 9 10
| @Target({ElementType.FIELD}) @Retention(RetentionPolicy.CLASS) @Deprecated public @interface Param { String name() default "";
String desc() default "No desc."; }
|
因为已经不在推荐使用,不多说了!
2.3 model
这个 package 下主要保存了一些数据类,这些类保存了跳转需要的数据,已经目前对象的类型:
用于保存路由跳转的数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class RouteMeta { private RouteType type; private Element rawType; private Class<?> destination; private String path; private String group; private int priority = -1; private int extra; private Map<String, Integer> paramsType; private String name;
private Map<String, Autowired> injectConfig;
public RouteMeta() { } ... ... ... ... }
|
其实可以看到,RouteMeta 内部的数据很多事 compiler 解析 Route、Autowired 注解获得的!
2.3.2 TypeWrapper
用于保存路由跳转的目标对象类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class TypeWrapper<T> { protected final Type type; protected TypeWrapper() { Type superClass = getClass().getGenericSuperclass(); type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; }
public Type getType() { return type; } }
|
TypeWrapper 是一个泛型类,泛型 T 表示目标对象类型!
后面我们再具体分析。
4 总结
本篇文章分析了 ARouter 中的 arouter-annotation 模块,其内部定义了 ARouter 必须的注解类,数据类,已经枚举类。
下篇文章将分析 arouter-compiler 模块,探寻在 App 编译期间,Gradle 事如何使用 arouter-compiler 对注解进行解析,和动态生成中间类的!