1. 程式人生 > >ARouter原始碼解析01-編譯生成檔案

ARouter原始碼解析01-編譯生成檔案

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 Builder檔案

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是通過載入這些路由清單,從而進行跳轉等操作的。

下篇文章,我們來驗證我們的猜想。