arouter原理
arouter有三个阶段,编译器编译、arouter初始化、arouter跳转。
编译器编译
arouter有三个最重要的注解@Route
、@Interceptor
和@Autowired
,这三个注解在编译期通过arouter-compiler这个框架生成需要的代码。
总结一下这个阶段主要就是将我们打注解的地方生成想应的代码,主要分为拦截器、route和变量
先来看RouteProcesser,他的作用就是生成@Route的相关代码,生成的代码是ARouter$$Group$$groupname
.
|
|
和注解说的一样,用于生成传入的类型,Map<String, Class<? extends IRouteGroup>>,
这个是给ARouter$$Root$$app用的。
*/
ParameterizedTypeName inputMapTypeOfRoot = ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(String.class),
ParameterizedTypeName.get(
ClassName.get(Class.class),
WildcardTypeName.subtypeOf(ClassName.get(type_IRouteGroup))
)
);
/*
RouteMeta>``` 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
同上面一样,生成Map<String, RouteMeta>,这是给Group和Provider使用。 */ 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(); // Ps. its param type same as groupParamSpec! /* Build method : 'loadInto' 生成接口的方法loadInto */ 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的Element。 for (Element element : routeElements) { TypeMirror tm = element.asType(); Route route = element.getAnnotation(Route.class); RouteMeta routeMeta; if (types.isSubtype(tm, type_Activity)) { // Activity logger.info(">>> Found activity route: " + tm.toString() + " <<<"); // Get all fields annotation by @Autowired Map<String, Integer> paramsType = new HashMap<>(); // 这个是用来放@AutoWired变量的 Map<String, Autowired> injectConfig = new HashMap<>(); for (Element field : element.getEnclosedElements()) { if (field.getKind().isField() && field.getAnnotation(Autowired.class) != null && !types.isSubtype(field.asType(), iProvider)) { // It must be field, then it has annotation, but it not be provider. // 找出带Autowired且不是IProvider的变量,也就是找出Arouter框架下获取页面传输的变量 Autowired paramConfig = field.getAnnotation(Autowired.class); // Autowired(name=""),这里用来获取是否有在注解里设置的名字,没有的话用变量名 String injectName = StringUtils.isEmpty(paramConfig.name()) ? field.getSimpleName().toString() : paramConfig.name(); // 将这个这个变量处理一下放入paramsType的map中,key为注解的名字,value是类型 paramsType.put(injectName, typeUtils.typeExchange(field)); // 将paramsType放入injectConfig的map中,key为注解的名字,value为paramsType injectConfig.put(injectName, paramConfig); } } // 将关于ACTIVITY的内容放到RouteMeta这个类中 routeMeta = new RouteMeta(route, element, RouteType.ACTIVITY, paramsType); // 将拥有变量信息的injectConfig放到RRouteMeta中 routeMeta.setInjectConfig(injectConfig); } else if (types.isSubtype(tm, iProvider)) { // IProvider logger.info(">>> Found provider route: " + tm.toString() + " <<<"); routeMeta = new RouteMeta(route, element, RouteType.PROVIDER, null); } else if (types.isSubtype(tm, type_Service)) { // Service logger.info(">>> Found service route: " + tm.toString() + " <<<"); routeMeta = new RouteMeta(route, element, RouteType.parse(SERVICE), null); } else if (types.isSubtype(tm, fragmentTm) || types.isSubtype(tm, fragmentTmV4)) { logger.info(">>> Found fragment route: " + tm.toString() + " <<<"); routeMeta = new RouteMeta(route, element, RouteType.parse(FRAGMENT), null); } else { // 这里可以得出结论,Route只能在Activity,Fragment,Service和Provider使用,不然就会报错 throw new RuntimeException("ARouter::Compiler >>> Found unsupported class type, type = [" + types.toString() + "]."); } // 这个方法就不深入了,groupMap是一个group为key,routeMetaSet为value的map,而routeMetaSet是存放RouteMeta的一个Set。这个方法的作用就是将我们这里已经创建好的RouteMeta放入routeMetaSet中 categories(routeMeta); } MethodSpec.Builder loadIntoMethodOfProviderBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO) .addAnnotation(Override.class) .addModifiers(PUBLIC) .addParameter(providerParamSpec); Map<String, List<RouteDoc>> docSource = new HashMap<>(); // Start generate java source, structure is divided into upper and lower levels, used for demand initialization. // 这里就开始生成代码了,这里的操作其实就有点机械化了,也就是没啥意思了,可以直接看生成类了。 return true; }}
接下来是AutowiredProcessor,用来生成
|
|
接下来是InterceptorProcessor
|
|
至此编译器编译的内容结束了,接下来我们来看看关于Arouter初始化做了啥。
1.将生成的类放入Warehouse想对应的列表中。
|
|