ARouter原始碼解析01-編譯生成檔案
阿新 • • 發佈:2019-02-09
Arouter原始碼解析
編譯時註解
ARouter採用了編譯時註解,在IDE編譯階段,即會生成相關檔案,以供後續使用。具體實現在arouter-compiler,由於編譯時註解的實現原理都大同小異,在這裡就不詳細說明了。
@AutoService(Processor.class) @SupportedOptions(KEY_MODULE_NAME) @SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({ANNOTATION_TYPE_ROUTE, ANNOTATION_TYPE_AUTOWIRED}) public class RouteProcessor extends AbstractProcessor { @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (CollectionUtils.isNotEmpty(annotations)) { Set<? extends Element> routeElements = roundEnv.getElementsAnnotatedWith(Route.class); //遍歷註解,儲存至map集合,再寫入到檔案中 this.parseRoutes(routeElements); return true; } return false; }
主要來看編譯之後,ARouter產生的檔案。檔案的路徑在
app/build/generated/source/apt/debug/com.alibaba.android.arouter/
資料夾下
ARouter$$Group $ $service: service組的路由清單
public class ARouter$$Group$$service implements IRouteGroup { @Override public void loadInto(Map<String, RouteMeta> atlas) { atlas.put("/service/hello", RouteMeta.build(RouteType.PROVIDER, HelloServiceImpl.class, "/service/hello", "service", null, -1, -2147483648)); atlas.put("/service/json", RouteMeta.build(RouteType.PROVIDER, JsonServiceImpl.class, "/service/json", "service", null, -1, -2147483648)); atlas.put("/service/single", RouteMeta.build(RouteType.PROVIDER, SingleService.class, "/service/single", "service", null, -1, -2147483648)); } }
ARouter$$Group $ $test: test組的路由清單
public class ARouter$$Group$$test implements IRouteGroup { @Override public void loadInto(Map<String, RouteMeta> atlas) { atlas.put("/test/activity1", RouteMeta.build(RouteType.ACTIVITY, Test1Activity.class, "/test/activity1", "test", new java.util.HashMap<String, Integer>(){{put("pac", 9); put("url", 8); }}, -1, -2147483648)); atlas.put("/test/activity2", RouteMeta.build(RouteType.ACTIVITY, Test2Activity.class, "/test/activity2", "test", new java.util.HashMap<String, Integer>(){{put("key1", 8); }} , -1, -2147483648)); atlas.put("/test/fragment", RouteMeta.build(RouteType.FRAGMENT, BlankFragment.class, "/test/fragment", "test", null, -1, -2147483648)); atlas.put("/test/webview", RouteMeta.build(RouteType.ACTIVITY, TestWebview.class, "/test/webview", "test", null, -1, -2147483648)); } }
ARouter$$Root $ $app: 路由清單總表
用於記錄組級別的路由清單,所有組級別的路由清單又會在此記錄。
public class ARouter$$Root$$app implements IRouteRoot {
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
routes.put("service", ARouter$$Group$$service.class);
routes.put("test", ARouter$$Group$$test.class);
}
}
ARouter$$Interceptors $ $app: 攔截器路由清單
可以發現攔截器的put順序,已在編譯階段,按照優先順序排序好了。
public class ARouter$$Interceptors$$app implements IInterceptorGroup {
@Override
public void loadInto(Map<Integer, Class<? extends IInterceptor>> interceptors) {
interceptors.put(3, Test2Interceptor.class);
interceptors.put(5, Test3Interceptor.class);
interceptors.put(7, Test1Interceptor.class);
}
}
ARouter$$Providers $ $app: Provider路由清單
public class ARouter$$Providers$$app implements IProviderGroup {
@Override
public void loadInto(Map<String, RouteMeta> providers) {
providers.put("com.alibaba.android.arouter.demo.testservice.HelloService",
RouteMeta.build(RouteType.PROVIDER, HelloServiceImpl.class, "/service/hello",
"service", null, -1, -2147483648));
providers.put("com.alibaba.android.arouter.facade.service.SerializationService",
RouteMeta.build(RouteType.PROVIDER, JsonServiceImpl.class, "/service/json", "service",
null, -1, -2147483648));
providers.put("com.alibaba.android.arouter.demo.testservice.SingleService",
RouteMeta.build(RouteType.PROVIDER, SingleService.class, "/service/single",
"service", null, -1, -2147483648));
}
}
從ARouter編譯的產物,我們可以猜測出,ARouter是通過載入這些路由清單,從而進行跳轉等操作的。
下篇文章,我們來驗證我們的猜想。