本系列文章主要分析 ARouter 框架的架构和原理。
这是阿里 ARouter 开源库的地址,大家可以直接访问
https://github.com/alibaba/ARouter
本篇博文主要分析 arouter-annotation 模块;
1 模块结构
下面我们来看看 arouter-annotation 的结构;
| 12
 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 类型!
| 12
 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
枚举类,每一个枚举成员都用于表示一个类型,包括基本类型,可序列化类型,字符串,对象等等;
| 12
 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:
| 12
 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 简单使用
| 12
 3
 4
 
 | @Route(path = "/xxx/xxx")public class PretreatmentServiceImpl implements PretreatmentService {
 ... ... ...
 }
 
 | 
| 12
 3
 4
 
 | @Route(path = "/test/activity")public class Test1Activity extends Activity {
 ... ... ...
 }
 
 | 
2.2.2 Autowired
用于修饰成员变量:
| 12
 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 简单使用
| 12
 3
 4
 
 | @Route(path = "/xxx/xxx")public class PretreatmentServiceImpl implements PretreatmentService {
 ... ... ...
 }
 
 | 
| 12
 3
 4
 
 | @Route(path = "/test/activity")public class Test1Activity extends Activity {
 ... ... ...
 }
 
 | 
2.2.3 Interceptor
用于注解拦截器:
| 12
 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 简单使用
| 12
 3
 4
 
 | @Interceptor(priority = 8, name = "测试用拦截器")public class TestInterceptor implements IInterceptor {
 ... ... ...
 }
 
 | 
2.2.4 Param(DEPRECATED)
这个注解也是用来修饰成员变量的,但是不推荐使用了,请使用 Autowired!
| 12
 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 下主要保存了一些数据类,这些类保存了跳转需要的数据,已经目前对象的类型:
用于保存路由跳转的数据:
| 12
 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
用于保存路由跳转的目标对象类型:
| 12
 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  对注解进行解析,和动态生成中间类的!