ARouter是阿里开源的路由组件,是 Android 平台中对页面、服务提供路由功能的中间件,常被用来进行组件化通讯。
常用的使用方式,推荐直接参考官网文档,写的非常详细。
链接:https://github.com/alibaba/ARouter/blob/master/README_CN.md
源码主要包含三个部分:
arouter-annotation:定义路由相关注解,Route(路由地址)、Autowired(属性装配)、Interceptor(路由拦截器)
arouter-compiler:注解处理器,用来生成路由表、属性装配器等java文件
arouter-api:路由api
大体思路是通过注解再编译期生成路由表,再ARouter.init()中将路由表加载到内存,然后调用api进行页面跳转等功能。
如果对自定义注解不了解的建议看下Java注解之编译时注解,另外arouter-compiler中使用JavaPoet Library来生成 Java 代码,JavaPoet 看这一篇就够了
arouter-annotation没什么说的,就是定义了路由需要的注解和数据结果
annotation
enums
model
定义了三个注解处理器:
RouteProcessor
/**
* 继承BaseProcessor,BaseProcessor中主要定义了类型、文件等工具类的引用、java版本进行初始化
**/
public class RouteProcessor extends BaseProcessor {
//...省略代码
//路由分组,前面也说了,路由是通过分组来进行管理的,每个路由分组对应一个java文件(ARouter$$Group$$组名),通过一个Root class(ARouter$$Root$$模块名称(Module))统一管理,ARouter.init时只会先加载Root,然后根据分组,在加载分组表。key:路由分组名称,value:路由表
private Map<String, Set<RouteMeta>> groupMap = new HashMap<>(); // ModuleName and routeMeta.
//模块路由分组入口。key:分组名称,value:路由分组java文件路径
private Map<String, String> rootMap = new TreeMap<>(); // Map of root metas, used for generate class file in order.
// IProvider类型
private TypeMirror iProvider = null;
// java文件生成器
private Writer docWriter; // Writer used for write doc
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
//...省略代码
//初始化工具和类型
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (CollectionUtils.isNotEmpty(annotations)) {
//获取Route注解
Set<? extends Element> routeElements = roundEnv.getElementsAnnotatedWith(Route.class);
try {
logger.info(">>> Found routes, start... <<<");
//处理Route注解,生成对应的路由java文件
this.parseRoutes(routeElements);
} catch (Exception e) {
logger.error(e);
}
return true;
}
return false;
}
//...省略代码
private void parseRoutes(Set<? extends Element> routeElements) throws IOException {
if (CollectionUtils.isNotEmpty(routeElements)) {
//...省略代码
//清空路由分组
rootMap.clear();
//获取activity类型
TypeMirror type_Activity = elementUtils.getTypeElement(ACTIVITY).asType();
//获取service类型
TypeMirror type_Service = elementUtils.getTypeElement(SERVICE).asType();
//获取fragment类型
TypeMirror fragmentTm = elementUtils.getTypeElement(FRAGMENT).asType();
//获取fragment V4类型
TypeMirror fragmentTmV4 = elementUtils.getTypeElement(Consts.FRAGMENT_V4).asType();
//获取路由组接口
TypeElement type_IRouteGroup = elementUtils.getTypeElement(IROUTE_GROUP);
//获取iProvider组接口,提供通过class获取iProvider
TypeElement type_IProviderGroup = elementUtils.getTypeElement(IPROVIDER_GROUP);
ClassName routeMetaCn = ClassName.get(RouteMeta.class);
ClassName routeTypeCn = ClassName.get(RouteType.class);
/*
定义方法参数类型:Map<String, Class<? extends IRouteGroup>>
*/
ParameterizedTypeName inputMapTypeOfRoot = ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(String.class),
ParameterizedTypeName.get(
ClassName.get(Class.class),
WildcardTypeName.subtypeOf(ClassName.get(type_IRouteGroup))
)
);
/*
*定义方法参数类型:Map<String, RouteMeta>
*/
ParameterizedTypeName inputMapTypeOfGroup = ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(String.class),
ClassName.get(RouteMeta.class)
);
/*
* 定义参数:(Map<String, Class<? extends IRouteGroup>> routes)
*/
ParameterSpec rootParamSpec = ParameterSpec.builder(inputMapTypeOfRoot, "routes").build();
/*
*定义参数:(Map<String, RouteMeta> atlas)
*/
ParameterSpec groupParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, "atlas").build();
/*
*定义参数:(Map<String, RouteMeta> providers)
*/
ParameterSpec providerParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, "providers").build(); // Ps. its param type same as groupParamSpec!
/*
*创建加载路由分组的方法:
*@Override
*public void loadInto(Map<String, Class<? extends IRouteGroup>> routes)
*/
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注解原始
for (Element element : routeElements) {
//获取元素类型
TypeMirror tm = element.asType();
//获取注解
Route route = element.getAnnotation(Route.class);
RouteMeta routeMeta;
if (types.isSubtype(tm, type_Activity)) {
// Activity
// 存放所有被Autowired注解的成员变量<名称,类型>
Map<String, Integer> paramsType = new HashMap<>();
//<名称,注解>
Map<String, Autowired> injectConfig = new HashMap<>();
//变量Activity所有子节点
for (Element field : element.getEnclosedElements()) {
//如果是成员变量并且不是iProvider的子类
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 paramConfig = field.getAnnotation(Autowired.class);
//注入名称,如果Autowired注解不带name,就以变量名做name
String injectName = StringUtils.isEmpty(paramConfig.name()) ? field.getSimpleName().toString() : paramConfig.name();
//添加名称、类型,paramsType和injectConfig主要用来生成文档和Uri参数解析,并不用于变量注入,activity成员变量的注入,主要还是靠AutowiredProcessor生产的注入器来实现。
paramsType.put(injectName, typeUtils.typeExchange(field));
injectConfig.put(injectName, paramConfig);
}
}
//创建RouteMeta
routeMeta = new RouteMeta(route, element, RouteType.ACTIVITY, paramsType);
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,这个基本上没用,ARouter目前并不支持启动服务
routeMeta = new RouteMeta(route, element, RouteType.parse(SERVICE), null);
} else if (types.isSubtype(tm, fragmentTm) || types.isSubtype(tm, fragmentTmV4)) {
//fragment
logger.info(">>> Found fragment route: " + tm.toString() + " <<<");
routeMeta = new RouteMeta(route, element, RouteType.parse(FRAGMENT), null);
} else {
throw new RuntimeException("ARouter::Compiler >>> Found unsupported class type, type = [" + types.toString() + "].");
}
//添加分组
categories(routeMeta);
}
/*
*创建加载iProvider表的方法:
*@override
*public void loadInto((Map<String, RouteMeta> providers))
*
*/
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.
//变量所有路由分组
for (Map.Entry<String, Set<RouteMeta>> entry : groupMap.entrySet()) {
//获取路由分组名称
String groupName = entry.getKey();
/*
*创建加载路由列表方法:
*@Override
*public void loadInfo(Map<String, RouteMeta> atlas)
*/
MethodSpec.Builder loadIntoMethodOfGroupBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO)
.addAnnotation(Override.class)
.addModifiers(PUBLIC)
.addParameter(groupParamSpec);
List<RouteDoc> routeDocList = new ArrayList<>();
// Build group method body
Set<RouteMeta> groupData = entry.getValue();
//遍历当前分组的所有节点
for (RouteMeta routeMeta : groupData) {
RouteDoc routeDoc = extractDocInfo(routeMeta);
ClassName className = ClassName.get((TypeElement) routeMeta.getRawType());
//根据不同的类型在不同的loadInfo方法中,添加语句,将当前节点加入对应的表中
switch (routeMeta.getType()) {
//当前节点是iProvider,在public void loadInto((Map<String, RouteMeta> providers))方法中加入providers.put(class,routeMeta)
case PROVIDER:
//获取所有继承的接口
List<? extends TypeMirror> interfaces = ((TypeElement) routeMeta.getRawType()).getInterfaces();
for (TypeMirror tm : interfaces) {
routeDoc.addPrototype(tm.toString());
//如果直接继承iProvider,providers.put("com.alibaba.android.arouter.facade.template.IProvider",routeMeta)
if (types.isSameType(tm, iProvider)) {
loadIntoMethodOfProviderBuilder.addStatement(
"providers.put($S, $T.build($T." + routeMeta.getType() + ", $T.class, $S, $S, null, " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + "))",
(routeMeta.getRawType()).toString(),
routeMetaCn,
routeTypeCn,
className,
routeMeta.getPath(),
routeMeta.getGroup());
} else if (types.isSubtype(tm, iProvider)) {
//如果是iProvider的子类,providers.put(当前类型的全路径,routeMeta)
loadIntoMethodOfProviderBuilder.addStatement(
"providers.put($S, $T.build($T." + routeMeta.getType() + ", $T.class, $S, $S, null, " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + "))",
tm.toString(), // So stupid, will duplicate only save class name.
routeMetaCn,
routeTypeCn,
className,
routeMeta.getPath(),
routeMeta.getGroup());
}
}
break;
default:
break;
}
// 其他类型
StringBuilder mapBodyBuilder = new StringBuilder();
//后面这部分主要用于生成文档,不影响路由表的生成
Map<String, Integer> paramsType = routeMeta.getParamsType();
Map<String, Autowired> injectConfigs = routeMeta.getInjectConfig();
if (MapUtils.isNotEmpty(paramsType)) {
List<RouteDoc.Param> paramList = new ArrayList<>();
for (Map.Entry<String, Integer> types : paramsType.entrySet()) {
mapBodyBuilder.append("put(\"").append(types.getKey()).append("\", ").append(types.getValue()).append("); ");
RouteDoc.Param param = new RouteDoc.Param();
Autowired injectConfig = injectConfigs.get(types.getKey());
param.setKey(types.getKey());
param.setType(TypeKind.values()[types.getValue()].name().toLowerCase());
param.setDescription(injectConfig.desc());
param.setRequired(injectConfig.required());
paramList.add(param);
}
routeDoc.setParams(paramList);
}
String mapBody = mapBodyBuilder.toString();
/*
*路由表加载方法
* public void loadInfo(Map<String, RouteMeta> atlas)中添加语句
* atlas.put(路由路径,routeMeta)
*/
loadIntoMethodOfGroupBuilder.addStatement(
"atlas.put($S, $T.build($T." + routeMeta.getType() + ", $T.class, $S, $S, " + (StringUtils.isEmpty(mapBody) ? null : ("new java.util.HashMap<String, Integer>(){{" + mapBodyBuilder.toString() + "}}")) + ", " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + "))",
routeMeta.getPath(),
routeMetaCn,
routeTypeCn,
className,
routeMeta.getPath().toLowerCase(),
routeMeta.getGroup().toLowerCase());
routeDoc.setClassName(className.toString());
routeDocList.add(routeDoc);
}
/* 生成路由组java文件:
public class ARouter$$Group&&组名 implements IRouteGroup{
@Override
void loadInto(Map<String, RouteMeta> atlas){
atlas.put(路由名,RouteMeta);
...
}
}
*/
String groupFileName = NAME_OF_GROUP + groupName;
JavaFile.builder(PACKAGE_OF_GENERATE_FILE,
TypeSpec.classBuilder(groupFileName)
.addJavadoc(WARNING_TIPS)
.addSuperinterface(ClassName.get(type_IRouteGroup))
.addModifiers(PUBLIC)
.addMethod(loadIntoMethodOfGroupBuilder.build())
.build()
).build().writeTo(mFiler);
logger.info(">>> Generated group: " + groupName + "<<<");
//将路由分组java文件路径添加到rootMap
rootMap.put(groupName, groupFileName);
docSource.put(groupName, routeDocList);
}
if (MapUtils.isNotEmpty(rootMap)) {
// Generate root meta by group name, it must be generated before root, then I can find out the class of group.
for (Map.Entry<String, String> entry : rootMap.entrySet()) {
/*
加载路由分组的方法添加语句
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes){
routes.put(分组名,路由分组java文件路径)
}
*/
loadIntoMethodOfRootBuilder.addStatement("routes.put($S, $T.class)", entry.getKey(), ClassName.get(PACKAGE_OF_GENERATE_FILE, entry.getValue()));
}
}
// Output route doc
if (generateDoc) {
docWriter.append(JSON.toJSONString(docSource, SerializerFeature.PrettyFormat));
docWriter.flush();
docWriter.close();
}
// Write provider into disk
/*
创建IPovider路由表类java文件
public class ARouter$$Providers$$模块名称 implements IProviderGroup{
@Override
public void loadInto(Map<String, RouteMeta> providers){
providers.put(IPovider或子类全路径,RouteMeta);
...
}
}
*/
String providerMapFileName = NAME_OF_PROVIDER + SEPARATOR + moduleName;
JavaFile.builder(PACKAGE_OF_GENERATE_FILE,
TypeSpec.classBuilder(providerMapFileName)
.addJavadoc(WARNING_TIPS)
.addSuperinterface(ClassName.get(type_IProviderGroup))
.addModifiers(PUBLIC)
.addMethod(loadIntoMethodOfProviderBuilder.build())
.build()
).build().writeTo(mFiler);
logger.info(">>> Generated provider map, name is " + providerMapFileName + " <<<");
// Write root meta into disk.
/*
创建路由分组管理类
public class ARouter$$Root$$模块名 implements IRouteRoot{
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes){
routes.put(组名,路由分组类class);
...
}
}
*/
String rootFileName = NAME_OF_ROOT + SEPARATOR + moduleName;
JavaFile.builder(PACKAGE_OF_GENERATE_FILE,
TypeSpec.classBuilder(rootFileName)
.addJavadoc(WARNING_TIPS)
.addSuperinterface(ClassName.get(elementUtils.getTypeElement(ITROUTE_ROOT)))
.addModifiers(PUBLIC)
.addMethod(loadIntoMethodOfRootBuilder.build())
.build()
).build().writeTo(mFiler);
logger.info(">>> Generated root, name is " + rootFileName + " <<<");
}
}
/**
* 添加routeMete到对应分组
*
* @param routeMete metas.
*/
private void categories(RouteMeta routeMete) {
//校验routeMete分组信息,如果没有组名,以第一个"/"与第二个"/"之间的名字作为组名,如果都不存在则无效
if (routeVerify(routeMete)) {
//根据组名获取分组
Set<RouteMeta> routeMetas = groupMap.get(routeMete.getGroup());
//如果分组不存在
if (CollectionUtils.isEmpty(routeMetas)) {
//创建一个分组
Set<RouteMeta> routeMetaSet = new TreeSet<>(new Comparator<RouteMeta>() {
@Override
public int compare(RouteMeta r1, RouteMeta r2) {
try {
return r1.getPath().compareTo(r2.getPath());
} catch (NullPointerException npe) {
logger.error(npe.getMessage());
return 0;
}
}
});
routeMetaSet.add(routeMete);
groupMap.put(routeMete.getGroup(), routeMetaSet);
} else {
//已经存在分组,直接添加
routeMetas.add(routeMete);
}
} else {
logger.warning(">>> Route meta verify error, group is " + routeMete.getGroup() + " <<<");
}
}
}
RouteProcessor主要生成了三个java文件:路径在对应模块的build/generated/ap_generated_sources/debug/out/com.alibaba.android.arouter.routes下
public class ARouter$$Group&&组名 implements IRouteGroup{
@Override
public void loadInto(Map<String, RouteMeta> atlas){
atlas.put(路由名,RouteMeta);
...
}
}
public class ARouter$$Providers$$模块名称 implements IProviderGroup{
@Override
public void loadInto(Map<String, RouteMeta> providers){
providers.put(IPovider或子类全路径,RouteMeta);
...
}
}
public class ARouter$$Root$$模块名 implements IRouteRoot{
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes){
routes.put(组名,路由分组类class);
...
}
}
例如:
public class ARouter$$Root$$app implements IRouteRoot {
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
routes.put("baseUrl", ARouter$$Group$$baseUrl.class);
routes.put("guide", ARouter$$Group$$guide.class);
routes.put("main", ARouter$$Group$$main.class);
routes.put("noteDb", ARouter$$Group$$noteDb.class);
routes.put("share", ARouter$$Group$$share.class);
routes.put("translateDb", ARouter$$Group$$translateDb.class);
routes.put("vip", ARouter$$Group$$vip.class);
}
}
public class ARouter$$Providers$$app implements IProviderGroup {
@Override
public void loadInto(Map<String, RouteMeta> providers) {
providers.put("com.iflytek.tibet.core.http.IBaseUrlProvider", RouteMeta.build(RouteType.PROVIDER, TibetUrlProvider.class, "/baseUrl/provider", "baseUrl", null, -1, -2147483648));
providers.put("com.iflytek.tibet.translate.db.provider.ITranslateDbProvider", RouteMeta.build(RouteType.PROVIDER, TibetTranslateDbProvider.class, "/translateDb/provider", "translateDb", null, -1, -2147483648));
providers.put("com.iflytek.tibet.note.db.INoteDbProvider", RouteMeta.build(RouteType.PROVIDER, TibetNoteDbProvider.class, "/noteDb/provider", "noteDb", null, -1, -2147483648));
providers.put("com.iflytek.tibet.core.share.IShareProvider", RouteMeta.build(RouteType.PROVIDER, TibetShareProvider.class, "/share/provider", "share", null, -1, -2147483648));
}
}
public class ARouter$$Group$$main implements IRouteGroup {
@Override
public void loadInto(Map<String, RouteMeta> atlas) {
atlas.put("/main/agreement", RouteMeta.build(RouteType.ACTIVITY, UserAgreementActivity.class, "/main/agreement", "main", null, -1, -2147483648));
}
}
InterceptorProcessor
public class InterceptorProcessor extends BaseProcessor {
/**
* 拦截器列表,<优先级,拦截器节点>,优先级从0开始,依次递减
*/
private Map<Integer, Element> interceptors = new TreeMap<>();
//...省略代码
/**
* {@inheritDoc}
*
* @param annotations
* @param roundEnv
*/
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (CollectionUtils.isNotEmpty(annotations)) {
//获取说有Interceptor注解
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Interceptor.class);
try {
//处理注解
parseInterceptors(elements);
} catch (Exception e) {
logger.error(e);
}
return true;
}
return false;
}
/**
* Parse tollgate.
*
* @param elements elements of tollgate.
*/
private void parseInterceptors(Set<? extends Element> elements) throws IOException {
if (CollectionUtils.isNotEmpty(elements)) {
//便利Interceptor注解原始
for (Element element : elements) {
//校验原始
if (verify(element)) {
//获取Interceptor注解
Interceptor interceptor = element.getAnnotation(Interceptor.class);
//检查是否已经存在相同优先级的拦截器,有就抛出异常
Element lastInterceptor = interceptors.get(interceptor.priority());
if (null != lastInterceptor) {
throw new IllegalArgumentException(
String.format(Locale.getDefault(), "More than one interceptors use same priority [%d], They are [%s] and [%s].",
interceptor.priority(),
lastInterceptor.getSimpleName(),
element.getSimpleName())
);
}
//不存在相同优先级的拦截器,加入列表
interceptors.put(interceptor.priority(), element);
} else {
logger.error("A interceptor verify failed, its " + element.asType());
}
}
//获取IInterceptor接口
TypeElement type_ITollgate = elementUtils.getTypeElement(IINTERCEPTOR);
//获取IInterceptorGroup接口
TypeElement type_ITollgateGroup = elementUtils.getTypeElement(IINTERCEPTOR_GROUP);
/**
*创建参数类型Map<Integer, Class<? extends IInterceptor>>
**/
ParameterizedTypeName inputMapTypeOfTollgate = ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(Integer.class),
ParameterizedTypeName.get(
ClassName.get(Class.class),
WildcardTypeName.subtypeOf(ClassName.get(type_ITollgate))
)
);
//创建参数Map<Integer, Class<? extends IInterceptor>> interceptors
ParameterSpec tollgateParamSpec = ParameterSpec.builder(inputMapTypeOfTollgate, "interceptors").build();
/**
* 创建方法
* @Override
* public void loadInfo(Map<Integer, Class<? extends IInterceptor>> interceptor)
*
*/
MethodSpec.Builder loadIntoMethodOfTollgateBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO)
.addAnnotation(Override.class)
.addModifiers(PUBLIC)
.addParameter(tollgateParamSpec);
/**
* 添加将各个拦截器加入列表的语句
* @Override
* public void loadInfo(Map<Integer, Class<? extends IInterceptor>> interceptor){
* interceptors.put(优先级,拦截器类信息)
* }
*/
if (null != interceptors && interceptors.size() > 0) {
// Build method body
for (Map.Entry<Integer, Element> entry : interceptors.entrySet()) {
loadIntoMethodOfTollgateBuilder.addStatement("interceptors.put(" + entry.getKey() + ", $T.class)", ClassName.get((TypeElement) entry.getValue()));
}
}
/**
* 创建添加Interceptor列表类
* public class ARouter$$Interceptors$$模块名称 implements IInterceptorGroup{
* @Override
* public void loadInto(Map<Integer, Class<? extends IInterceptor>> interceptor){
* interceptors.put(优先级,拦截器类信息);
* }
* }
*/
JavaFile.builder(PACKAGE_OF_GENERATE_FILE,
TypeSpec.classBuilder(NAME_OF_INTERCEPTOR + SEPARATOR + moduleName)
.addModifiers(PUBLIC)
.addJavadoc(WARNING_TIPS)
.addMethod(loadIntoMethodOfTollgateBuilder.build())
.addSuperinterface(ClassName.get(type_ITollgateGroup))
.build()
).build().writeTo(mFiler);
}
}
/**
* 校验原始是不是被Interceptor注解,并且是IInterceptor子类
*
* @param element Interceptor taw type
* @return verify result
*/
private boolean verify(Element element) {
Interceptor interceptor = element.getAnnotation(Interceptor.class);
return null != interceptor && ((TypeElement) element).getInterfaces().contains(iInterceptor);
}
}
主要生成一个按优先级添加IInterceptor列表的类,在ARouter.init()时通过此类将IInterceptor列表加载进内存。然后通过InterceptorService来进行拦截器管理。后续在详解InterceptorService
public class ARouter$$Interceptors$$模块名称 implements IInterceptorGroup{
@Override
public void loadInto(Map<Integer, Class<? extends IInterceptor>> interceptor){
interceptors.put(优先级,拦截器类信息);
}
}
AutowiredProcessor
public class AutowiredProcessor extends BaseProcessor {
/**
* 需要自动装配的成员变量和它的父节点类列表<父节点类,当前类需要自动装配的成员变量列表>
*/
private Map<TypeElement, List<Element>> parentAndChild = new HashMap<>();
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
if (CollectionUtils.isNotEmpty(set)) {
try {
logger.info(">>> Found autowired field, start... <<<");
//遍历所有Autowired注解,并按父节点类加入列表
categories(roundEnvironment.getElementsAnnotatedWith(Autowired.class));
//根据父节点类列表生成对应装配类
generateHelper();
} catch (Exception e) {
logger.error(e);
}
return true;
}
return false;
}
/**
* @throws IOException
* @throws IllegalAccessException
*/
private void generateHelper() throws IOException, IllegalAccessException {
//...省略代码
//创建参数Object target
ParameterSpec objectParamSpec = ParameterSpec.builder(TypeName.OBJECT, "target").build();
if (MapUtils.isNotEmpty(parentAndChild)) {
//遍历parentAndChild
for (Map.Entry<TypeElement, List<Element>> entry : parentAndChild.entrySet()) {
/**
* 创建inject方法
* @Override
* public void inject(Object target)
*/
MethodSpec.Builder injectMethodBuilder = MethodSpec.methodBuilder(METHOD_INJECT)
.addAnnotation(Override.class)
.addModifiers(PUBLIC)
.addParameter(objectParamSpec);
TypeElement parent = entry.getKey();
List<Element> childs = entry.getValue();
//获取父节点类的限定名
String qualifiedName = parent.getQualifiedName().toString();
//获取父节点类包名
String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf("."));
//父节点类对应装配器类名
String fileName = parent.getSimpleName() + NAME_OF_AUTOWIRED;
logger.info(">>> Start process " + childs.size() + " field in " + parent.getSimpleName() + " ... <<<");
/**
* 创建装配器类
* public class 父节点类包名$$ARouter$$Autowired implements ISyringe{
* public void inject(Object target){
*
* }
* }
*/
TypeSpec.Builder helper = TypeSpec.classBuilder(fileName)
.addJavadoc(WARNING_TIPS)
.addSuperinterface(ClassName.get(type_ISyringe))
.addModifiers(PUBLIC);
//创建变量 SerializationService serializationService,用来对Object变量进行序列化和反序列化
FieldSpec jsonServiceField = FieldSpec.builder(TypeName.get(type_JsonService.asType()), "serializationService", Modifier.PRIVATE).build();
helper.addField(jsonServiceField);
//inject方法中添加初始化serializationService语句
injectMethodBuilder.addStatement("serializationService = $T.getInstance().navigation($T.class)", ARouterClass, ClassName.get(type_JsonService));
//inject方法中添加对参数target进行强制类型转换语句
injectMethodBuilder.addStatement("$T substitute = ($T)target", ClassName.get(parent), ClassName.get(parent));
// 遍历待装配变量列表
for (Element element : childs) {
Autowired fieldConfig = element.getAnnotation(Autowired.class);
//获取装配变量名
String fieldName = element.getSimpleName().toString();
//如果变量类型是iProvider,这通过ARouter.getInstance().navigation(类),来进行装配
if (types.isSubtype(element.asType(), iProvider)) { // It's provider
if ("".equals(fieldConfig.name())) { // User has not set service path, then use byType.
// Getter
injectMethodBuilder.addStatement(
"substitute." + fieldName + " = $T.getInstance().navigation($T.class)",
ARouterClass,
ClassName.get(element.asType())
);
} else { // use byName
// Getter
injectMethodBuilder.addStatement(
"substitute." + fieldName + " = ($T)$T.getInstance().build($S).navigation()",
ClassName.get(element.asType()),
ARouterClass,
fieldConfig.name()
);
}
// Validater
if (fieldConfig.required()) {
injectMethodBuilder.beginControlFlow("if (substitute." + fieldName + " == null)");
injectMethodBuilder.addStatement(
"throw new RuntimeException(\"The field '" + fieldName + "' is null, in class '\" + $T.class.getName() + \"!\")", ClassName.get(parent));
injectMethodBuilder.endControlFlow();
}
} else { // It's normal intent value
String originalValue = "substitute." + fieldName;
String statement = "substitute." + fieldName + " = " + buildCastCode(element) + "substitute.";
boolean isActivity = false;
//如果是activity则通过getIntent()获取传递的数据
if (types.isSubtype(parent.asType(), activityTm)) { // Activity, then use getIntent()
isActivity = true;
statement += "getIntent().";
} else if (types.isSubtype(parent.asType(), fragmentTm) || types.isSubtype(parent.asType(), fragmentTmV4)) { // Fragment, then use getArguments()
//如果是fragment则通过getArguments()获取传递的数据
statement += "getArguments().";
} else {
throw new IllegalAccessException("The field [" + fieldName + "] need autowired from intent, its parent must be activity or fragment!");
}
//根据变量的不同类型,创建对应的获取语句
statement = buildStatement(originalValue, statement, typeUtils.typeExchange(element), isActivity);
if (statement.startsWith("serializationService.")) { // Not mortals
injectMethodBuilder.beginControlFlow("if (null != serializationService)");
injectMethodBuilder.addStatement(
"substitute." + fieldName + " = " + statement,
(StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name()),
ClassName.get(element.asType())
);
injectMethodBuilder.nextControlFlow("else");
injectMethodBuilder.addStatement(
"$T.e(\"" + Consts.TAG + "\", \"You want automatic inject the field '" + fieldName + "' in class '$T' , then you should implement 'SerializationService' to support object auto inject!\")", AndroidLog, ClassName.get(parent));
injectMethodBuilder.endControlFlow();
} else {
injectMethodBuilder.addStatement(statement, StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name());
}
// Validator
if (fieldConfig.required() && !element.asType().getKind().isPrimitive()) { // Primitive wont be check.
injectMethodBuilder.beginControlFlow("if (null == substitute." + fieldName + ")");
injectMethodBuilder.addStatement(
"$T.e(\"" + Consts.TAG + "\", \"The field '" + fieldName + "' is null, in class '\" + $T.class.getName() + \"!\")", AndroidLog, ClassName.get(parent));
injectMethodBuilder.endControlFlow();
}
}
}
helper.addMethod(injectMethodBuilder.build());
// 生成装配器类文件
JavaFile.builder(packageName, helper.build()).build().writeTo(mFiler);
}
}
}
}
主要是生成对应类的装配器,路径在\build\generated\ap_generated_sources\debug\out\对应包名\对应使用Autowired的类
public class 父节点类包名$$ARouter$$Autowired implements ISyringe{
public void inject(Object target){
//例如
TestActivity substitute = (TestActivity )target;
substitute.text = substitute.getIntent().getIntExtra("text");
}
}
然后在调用ARouter.getInstance().inject(this);时,通过AutowiredService管理类创建装配器类,然后进行变量装配。后面详解
ARouter初始化一般是在Application中调用ARouter.init(context);
public static void init(Application application) {
if (!hasInit) {
logger = _ARouter.logger;
_ARouter.logger.info(Consts.TAG, "ARouter init start.");
hasInit = _ARouter.init(application);
if (hasInit) {
_ARouter.afterInit();
}
_ARouter.logger.info(Consts.TAG, "ARouter init over.");
}
}
最终会通过_ARouter.init(application)调用LogisticsCenter.init(mContext, executor)
public class LogisticsCenter {
public synchronized static void init(Context context, ThreadPoolExecutor tpe) throws HandlerException {
try {
//...省略代码
if (registerByPlugin) {
logger.info(TAG, "Load router map by arouter-auto-register plugin.");
} else {
Set<String> routerMap;
//...省略代码
// 如果是debug版本或者app版本更新,就重新加载所有com.alibaba.android.arouter.routes.*文件路径,不然就从sp中获取,这样只有第一次慢一点
if (ARouter.debuggable() || PackageUtils.isNewVersion(context)) {
logger.info(TAG, "Run with debug mode or new install, rebuild router map.");
// These class was generated by arouter-compiler.
routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);
if (!routerMap.isEmpty()) {
context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(AROUTER_SP_KEY_MAP, routerMap).apply();
}
PackageUtils.updateVersion(context); // Save new version name when router map update finishes.
} else {
logger.info(TAG, "Load router map from cache.");
routerMap = new HashSet<>(context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(AROUTER_SP_KEY_MAP, new HashSet<String>()));
}
logger.info(TAG, "Find router map finished, map size = " + routerMap.size() + ", cost " + (System.currentTimeMillis() - startInit) + " ms.");
startInit = System.currentTimeMillis();
//变量所有的路由文件
for (String className : routerMap) {
if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_ROOT)) {
//如果是GroupRoot,通过反射创建对象,并加载到Warehouse.groupsIndex列表中
// This one of root elements, load root.
((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);
} else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_INTERCEPTORS)) {
// Load interceptorMeta
//如果是拦截器Group,通过反射创建对象,并加载到Warehouse.interceptorsIndex列表中
((IInterceptorGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.interceptorsIndex);
} else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_PROVIDERS)) {
// Load providerIndex
//如果是ProviderGroup,通过反射创建对象,并加载到Warehouse.providersIndex列表中
((IProviderGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.providersIndex);
}
}
}
logger.info(TAG, "Load root element finished, cost " + (System.currentTimeMillis() - startInit) + " ms.");
if (Warehouse.groupsIndex.size() == 0) {
logger.error(TAG, "No mapping files were found, check your configuration please!");
}
if (ARouter.debuggable()) {
logger.debug(TAG, String.format(Locale.getDefault(), "LogisticsCenter has already been loaded, GroupIndex[%d], InterceptorIndex[%d], ProviderIndex[%d]", Warehouse.groupsIndex.size(), Warehouse.interceptorsIndex.size(), Warehouse.providersIndex.size()));
}
} catch (Exception e) {
throw new HandlerException(TAG + "ARouter init logistics center exception! [" + e.getMessage() + "]");
}
}
}
初始化主要完成了
_ARouter.init初始化完,注意调用了_ARouter.afterInit()
final class _ARouter {
//...
static void afterInit() {
interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor").navigation();
}
//...
}
这里初始化了拦截器管理类,后面再详解如何创建及什么时候使用。
路由的基本使用:ARouter.getInstance().build("app/main").withBoolean("state",true).navigation();
ARouter.build会直接调用_ARouter.getInstance().build(path),build有多个重载方法,build(string)、build(url),build(path、group),最后调用都一样,我们以build(string)为例。
final class _ARouter {
//...省略代码
protected Postcard build(String path) {
//判空
if (TextUtils.isEmpty(path)) {
throw new HandlerException(Consts.TAG + "Parameter is invalid!");
} else {
//获取路由替换服务,PathReplaceService就是一个IProvider,提供forString、forUrl对路由地址进行替换。获取过程后面详解。
PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
if (null != pService) {
//如果路由替换服务不为空,调用替换方法
path = pService.forString(path);
}
//调用重载方法build(path,group)返回Postcard
return build(path, extractGroup(path));
}
}
//...省略代码
}
在build(path)方法中首先会通过PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);获取我们自定义的PathReplaceService,例如:
@Route(path = "/app/replace")
public class MyPathReplaceService implements PathReplaceService {
@Override
public String forString(String path) {
if(path.equals(ActivityConsts.ACTIVITY_URL_SECOND)){
return ActivityConsts.ACTIVITY_URL_THIRD;
}
return path;
}
@Override
public Uri forUri(Uri uri) {
return null;
}
@Override
public void init(Context context) {
}
}
如果获取PathReplaceService不为空,则调用forString(path)对当前路由进行替换。我们先来看一下PathReplaceService的获取方式。PathReplaceService继承IProvider接口,所以它的获取方式IProvider的获取方式一样,所以后面所有获取IProvider都可以参考这个。一层层跟进,最后会调用
final class _ARouter {
//...省略代码
protected <T> T navigation(Class<? extends T> service) {
try {
//通过Warehouse.providersIndex表,根据class name获取Postcard
Postcard postcard = LogisticsCenter.buildProvider(service.getName());
// Compatible 1.0.5 compiler sdk.
// Earlier versions did not use the fully qualified name to get the service
if (null == postcard) {
// No service, or this service in old version.
postcard = LogisticsCenter.buildProvider(service.getSimpleName());
}
if (null == postcard) {
return null;
}
//校验Postcard,添加相应属性,并通过反射创建相应IProvider对象
LogisticsCenter.completion(postcard);
return (T) postcard.getProvider();
} catch (NoRouteFoundException ex) {
logger.warning(Consts.TAG, ex.getMessage());
return null;
}
}
//...省略代码
}
跟进看一下LogisticsCenter.completion
public class LogisticsCenter {
//...省略代码
public synchronized static void completion(Postcard postcard) {
if (null == postcard) {
throw new NoRouteFoundException(TAG + "No postcard!");
}
//从Warehouse.routes路由表加载对应路由信息
RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
//如果还未加载过对应路由
if (null == routeMeta) {
//先获取对应group分组
Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());
//如果不存在对应分组,直接报错
if (null == groupMeta) {
throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]");
} else {
// Load route and cache it into memory, then delete from metas.
try {
if (ARouter.debuggable()) {
logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] starts loading, trigger by [%s]", postcard.getGroup(), postcard.getPath()));
}
//通过反射创建对应分组对象
IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();
//将该分组下所有路由信息加载到Warehouse.routes
iGroupInstance.loadInto(Warehouse.routes);
//从分组列表中删除对应分组,避免多次加载
Warehouse.groupsIndex.remove(postcard.getGroup());
if (ARouter.debuggable()) {
logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] has already been loaded, trigger by [%s]", postcard.getGroup(), postcard.getPath()));
}
} catch (Exception e) {
throw new HandlerException(TAG + "Fatal exception when loading group meta. [" + e.getMessage() + "]");
}
//重新调用completion
completion(postcard);
}
} else {
//如果已加载过对应路由,添加相应属性
postcard.setDestination(routeMeta.getDestination());
postcard.setType(routeMeta.getType());
postcard.setPriority(routeMeta.getPriority());
postcard.setExtra(routeMeta.getExtra());
//如果是通过Uri获取路由
Uri rawUri = postcard.getUri();
if (null != rawUri) {
//获取Uri中的参数,并根据Autowired注解变量的类型,将参数设置到Bundle中,用于后面变量的自动装配
Map<String, String> resultMap = TextUtils.splitQueryParameters(rawUri);
Map<String, Integer> paramsType = routeMeta.getParamsType();
if (MapUtils.isNotEmpty(paramsType)) {
for (Map.Entry<String, Integer> params : paramsType.entrySet()) {
setValue(postcard,
params.getValue(),
params.getKey(),
resultMap.get(params.getKey()));
}
postcard.getExtras().putStringArray(ARouter.AUTO_INJECT, paramsType.keySet().toArray(new String[]{}));
}
postcard.withString(ARouter.RAW_URI, rawUri.toString());
}
switch (routeMeta.getType()) {
case PROVIDER:
//如果是注解是PROVIDER类型
Class<? extends IProvider> providerMeta = (Class<? extends IProvider>) routeMeta.getDestination();
//判断Warehouse.providers列表中是否已经创建了对应的IProvider
IProvider instance = Warehouse.providers.get(providerMeta);
if (null == instance) {
//如果没有创建,通过反射创建对应IProvider对象,并添加到Warehouse.providers列表中
IProvider provider;
try {
provider = providerMeta.getConstructor().newInstance();
provider.init(mContext);
Warehouse.providers.put(providerMeta, provider);
instance = provider;
} catch (Exception e) {
throw new HandlerException("Init provider failed! " + e.getMessage());
}
}
//对postcard中的IProvider进行赋值
postcard.setProvider(instance);
//设置IProvider不能被拦截
postcard.greenChannel();
break;
case FRAGMENT:
postcard.greenChannel();
default:
break;
}
}
}
//...省略代码
}
Postcard可以理解为路由组装类,类似于builder模式
定义了activity跳转、fragment传递数据的Bundle,并提供设置参数的接口及Object序列化服务
支持设置activity跳转动画及启动模式
如果当前RouteMeta的类型是Iprovider,会提供provider实例
greenChannel标记当前路由是否可以被拦截
public final class Postcard extends RouteMeta {
// Base
private Uri uri;
//传递数据
private Bundle mBundle;
//activity启动模式
private int flags = -1;
//拦截超时
private int timeout = 300;
//如果当前路由是IProvider,就会被设置
private IProvider provider;
//表示是否会被拦截,true不能被拦截
private boolean greenChannel;
//mBundle设置Object是序列化服务
private SerializationService serializationService;
//activity跳转动画
private Bundle optionsCompat; // The transition animation of activity
private int enterAnim;
private int exitAnim;
//...省略代码
public void navigation(Activity mContext, int requestCode, NavigationCallback callback) {
ARouter.getInstance().navigation(mContext, this, requestCode, callback);
}
//...省略代码
}
执行路由Postcard.navigation(),直接执行ARouter.getInstance().navigation(mContext, this, requestCode, callback);最终都会调用_ARouter.getInstance().navigation
final class _ARouter {
/**
* 执行路由
*
* @param context Activity or null.
* @param postcard Route metas 路由
* @param requestCode RequestCode activity请求码
* @param callback 路由执行回调
*/
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
//获取预处理服务,PretreatmentService就是一个IProvider,获取方式和PathReplaceService一样
PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);
if (null != pretreatmentService && !pretreatmentService.onPretreatment(context, postcard)) {
//预处理服务不为空,并且预处理失败,则不执行路由
return null;
}
try {
/**
* 补全路由数据,由于build返回的Postcard对象,是我们手动填写的路由地址,但路由并不一定存在,
* 所有通过LogisticsCenter.completion来校验是否存在此路由,并补全Postcard相关成员变量
*/
LogisticsCenter.completion(postcard);
} catch (NoRouteFoundException ex) {
//路由不存在
if (debuggable()) {
// debug模式就Toast提醒
runInMainThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, "There's no route matched!\n" +
" Path = [" + postcard.getPath() + "]\n" +
" Group = [" + postcard.getGroup() + "]", Toast.LENGTH_LONG).show();
}
});
}
/**
* 如果回调不为空,执行回调onLost,如果回调为空,执行降级策略,所有要注意设置了回调是不会执行降级策略的
*/
if (null != callback) {
callback.onLost(postcard);
} else {
//获取降级策略服务,DegradeService就是一个IProvider
DegradeService degradeService = ARouter.getInstance().navigation(DegradeService.class);
if (null != degradeService) {
degradeService.onLost(context, postcard);
}
}
return null;
}
//回调onFound
if (null != callback) {
callback.onFound(postcard);
}
//是否能被拦截
if (!postcard.isGreenChannel()) {
//通过InterceptorService服务,检查是否被拦截
interceptorService.doInterceptions(postcard, new InterceptorCallback() {
/**
* 继续执行
* @param postcard route meta
*/
@Override
public void onContinue(Postcard postcard) {
_navigation(context, postcard, requestCode, callback);
}
/**
* 被拦截
* @param exception Reson of interrupt.
*/
@Override
public void onInterrupt(Throwable exception) {
if (null != callback) {
callback.onInterrupt(postcard);
}
}
});
} else {
//继续执行路由
return _navigation(context, postcard, requestCode, callback);
}
return null;
}
private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
final Context currentContext = null == context ? mContext : context;
switch (postcard.getType()) {
//如果是Activity路由
case ACTIVITY:
// 创建Intent并添加数据
final Intent intent = new Intent(currentContext, postcard.getDestination());
intent.putExtras(postcard.getExtras());
// 设置启动模式
int flags = postcard.getFlags();
if (-1 != flags) {
intent.setFlags(flags);
} else if (!(currentContext instanceof Activity)) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
// 设置action
String action = postcard.getAction();
if (!TextUtils.isEmpty(action)) {
intent.setAction(action);
}
// 在主线程启动activity
runInMainThread(new Runnable() {
@Override
public void run() {
startActivity(requestCode, currentContext, intent, postcard, callback);
}
});
break;
case PROVIDER:
//如果是IProvider路由,直接返回
return postcard.getProvider();
case BOARDCAST:
case CONTENT_PROVIDER:
case FRAGMENT:
/**
* 如果是BoardCast、ContentProvider、Fragment路由,通过反射调用无参数构造函数继续创建,
* 所有BoardCast、ContentProvider类型基本上没什么用
*/
Class fragmentMeta = postcard.getDestination();
try {
Object instance = fragmentMeta.getConstructor().newInstance();
if (instance instanceof Fragment) {
((Fragment) instance).setArguments(postcard.getExtras());
} else if (instance instanceof android.support.v4.app.Fragment) {
((android.support.v4.app.Fragment) instance).setArguments(postcard.getExtras());
}
return instance;
} catch (Exception ex) {
logger.error(Consts.TAG, "Fetch fragment instance error, " + TextUtils.formatStackTrace(ex.getStackTrace()));
}
case METHOD:
case SERVICE:
default:
return null;
}
return null;
}
}
路由的执行过程到这就结束了。
通过前面分析我们知道,路由拦截是通过InterceptorService实现的,InterceptorService的初始化后 _ARouter.afterInit()进行
static void afterInit() {
// Trigger interceptor init, use byName.
interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor").navigation();
}
通过路由"/arouter/service/interceptor"获取InterceptorService的实例InterceptorServiceImpl,定义在arouter-api。由于InterceptorServiceImpl继承IProvider接口,在初始化后会调用对应init()方法。
@Route(path = "/arouter/service/interceptor")
public class InterceptorServiceImpl implements InterceptorService {
private static boolean interceptorHasInit;
private static final Object interceptorInitLock = new Object();
@Override
public void init(final Context context) {
//异步加载拦截器
LogisticsCenter.executor.execute(new Runnable() {
@Override
public void run() {
//在ARouter.init中会将所有定义的interceptor加载到Warehouse.interceptorsIndex列表中
//如果Warehouse.interceptorsIndex不为空
if (MapUtils.isNotEmpty(Warehouse.interceptorsIndex)) {
//遍历所有拦截器,由于Warehouse.interceptorsIndex是TreeMap类型,默认按key的默认顺序进行排序,而key是Integer类型,所以key越小,优先级越高。
for (Map.Entry<Integer, Class<? extends IInterceptor>> entry : Warehouse.interceptorsIndex.entrySet()) {
Class<? extends IInterceptor> interceptorClass = entry.getValue();
try {
//通过反射创建IInterceptor对应实例
IInterceptor iInterceptor = interceptorClass.getConstructor().newInstance();
//调用init进行初始化
iInterceptor.init(context);
//添加到Warehouse.interceptors列表
Warehouse.interceptors.add(iInterceptor);
} catch (Exception ex) {
throw new HandlerException(TAG + "ARouter init interceptor error! name = [" + interceptorClass.getName() + "], reason = [" + ex.getMessage() + "]");
}
}
//设置加载完成标志位
interceptorHasInit = true;
logger.info(TAG, "ARouter interceptors init over.");
//释放同步锁
synchronized (interceptorInitLock) {
interceptorInitLock.notifyAll();
}
}
}
});
}
}
InterceptorServiceImpl.init(context)主要是通过异步方式,按优先级加载所有的 interceptor:
执行拦截doInterceptions
public class InterceptorServiceImpl implements InterceptorService {
private static boolean interceptorHasInit;
private static final Object interceptorInitLock = new Object();
@Override
public void doInterceptions(final Postcard postcard, final InterceptorCallback callback) {
//如果拦截器列表不为空
if (null != Warehouse.interceptors && Warehouse.interceptors.size() > 0) {
//等待拦截器列表初始化完成,10秒超时
checkInterceptorsInitStatus();
//如果超时后还未初始化完成,直接回调拦截
if (!interceptorHasInit) {
callback.onInterrupt(new HandlerException("Interceptors initialization takes too much time."));
return;
}
//异步执行拦截
LogisticsCenter.executor.execute(new Runnable() {
@Override
public void run() {
CancelableCountDownLatch interceptorCounter = new CancelableCountDownLatch(Warehouse.interceptors.size());
try {
//通过interceptorCounter根据优先级串行调用拦截器,如果被拦截,取消interceptorCounter,继续执行interceptorCounter.await之后代码
_excute(0, interceptorCounter, postcard);
//等待遍历拦截器列表,如果interceptorCounter未减为0或者超时,则阻塞等待
interceptorCounter.await(postcard.getTimeout(), TimeUnit.SECONDS);
if (interceptorCounter.getCount() > 0) {
//如果interceptorCounter.getCount() > 0,证明是超时唤醒
callback.onInterrupt(new HandlerException("The interceptor processing timed out."));
} else if (null != postcard.getTag()) {
//在路由被拦截时,会设置tag,所以null != postcard.getTag证明被拦截
callback.onInterrupt(new HandlerException(postcard.getTag().toString()));
} else {
//不拦截,继续执行
callback.onContinue(postcard);
}
} catch (Exception e) {
callback.onInterrupt(e);
}
}
});
} else {
//不拦截,继续执行
callback.onContinue(postcard);
}
}
}
使用@Autowired注解后,需要在使用之前会调用ARouter.getInstance().inject(this)来完成自动装配。
static void inject(Object thiz) {
AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation());
if (null != autowiredService) {
autowiredService.autowire(thiz);
}
}
自动装配主要是通过AutowiredService来进行管理的,通过“/arouter/service/autowired”路由获取到的是AutowiredServiceImpl。定义在arouter-api中
@Route(path = "/arouter/service/autowired")
public class AutowiredServiceImpl implements AutowiredService {
/**
* ISyringe缓存
*/
private LruCache<String, ISyringe> classCache;
/**
* 黑名单,不能autowire的类名
*/
private List<String> blackList;
@Override
public void autowire(Object instance) {
String className = instance.getClass().getName();
try {
//不存在黑名单
if (!blackList.contains(className)) {
//获取缓存
ISyringe autowiredHelper = classCache.get(className);
if (null == autowiredHelper) {
//不存在缓存,通过反射创建对应装配器实例。前面我们说过AutowiredProcessor会为每个包含Autowired注解的类生成一个装配器类
autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance();
}
//进行装配
autowiredHelper.inject(instance);
//添加到缓存,避免多次创建
classCache.put(className, autowiredHelper);
}
} catch (Exception ex) {
//加入黑名单
blackList.add(className);
}
}
}
主要通过反射创建对应AutowiredProcessor生成的装配器类,调用装配器类的inject进行注入。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章