ARouter 原理

1,341 阅读7分钟

探索 ARouter 原理

探索Android路由框架-ARouter之深挖源码(二)

ARouter 原理概述

ARouter 是阿里开源的一款帮助 Android APP 进行组件化改造的路由框架,可以实现在同一个项目中互不依赖的的模块的 Activity 之间跳转。简单的说,就是用来跳转界面的,不像平时用到的显式或隐式跳转,只需要在对应的界面上添加注解,就可以实现跳转:

@Route(path = "/test/activity")
public class YourActivity extend Activity {
    ...
}

//跳转
ARouter.getInstance().build("/test/activity").navigation();

可以想到,关键跳转过程是通过path跳转到具体的activity,那么原理无非就是把pathActivity一一对应起来就行了。其实就是通过apt注解处理工具,把path和activity关联起来了。主要有以下几个步骤:

  • 代码里加入的@Route注解,会在编译时期通过apt生成一些存储path和activity.class映射关系的类文件
  • app进程启动的时候会加载这些类文件,把保存这些映射关系的数据读到内存里(保存在map里)
  • 进行路由跳转的时候,通过build()方法传入要到达页面的路由地址,ARouter会通过它自己存储的路由表找到路由地址对应的Activity.class
  • 然后new Intent方法,如果有调用ARouterwithString()方法,就会调用intent.putExtra(String name, String value)方法添加参数
  • 最后调用navigation()方法,它的内部会调用startActivity(intent)进行跳转

当我们调用 ARouter 的 build() 方法后,会获取到一个 Postcard 对象,我们调用的 navigation() 方法就是 Postcard 的 navigation() 方法,Postcard 的 navigation() 方法会调用到 _ARoute 的 navigation() 方法中,在这方法中,首先会处理预处理服务,然后会让 LogisticsCenter 填充 Postcard 中的信息,如果 LogisticsCenter 没有找到对应的路由信息的话,就会走降级策略的逻辑,如果 LogisticsCenter 找到对应的路由信息的话,就会判断是不是走绿色通道,如果不走绿色通道的话就由拦截器链决定要不要跳转。如果走绿色通道的话,就直接按 Fragment 和 Activity 等不同的类型进行跳转,在跳转完成后,如果设置了跳转回调, LogisticsCenter 就会调用这个回调。

ARouter 的路由参数拦截器都是用注解来标注的。

RouteProcessor 是一个注解处理器,是 AbstractProcessor 的子类。在 RouteProcessor 的 process() 方法中,会调用 parseRoutes() 方法,parseRoutes() 方法会用 JavaPoet API 来生成 Java 代码,具体的代码就是 Activity 等类的 Class 信息。除了 RouteProcessor ,ARouter 中还有参数注解处理器 AutowiredProcessor 和拦截器注解处理器 InterceptorProcessor ,它们的原理和 RouteProcessor 是一样的。


ARouter 的路由参数拦截器都是用注解来标注的。

ARouter 的跳转是基于路由表 RouterMap 实现的,负责生成路由表的是 RouteProcessor ,负责加载路由表的是 LogisticsCenterRegisterTransform

注解分为运行时注解编译时注解编译时注解是依赖注解处理工具 APT(Annotation Processing Tool)实现的,用于在编译时扫描和处理注解,通过 APT 我们能少写很多模板代码。在编译时,编译器会检查 AbstractProcessor 的子类,并调用 AbstractProcessor 的子类的 process() 方法,然后把添加了注解的元素都传到 process() 方法中,这样我们就可以在 process() 函数中生成新的 Java 类文件。

RouteProcessor 是一个注解处理器,是 AbstractProcessor 的子类。在 RouteProcessor 的 process() 方法中,会调用 parseRoutes() 方法,parseRoutes() 方法会用 JavaPoet API 来生成 Java 代码,具体的代码就是 Activity 等类的 Class 信息。除了 RouteProcessor ,ARouter 中还有参数注解处理器 AutowiredProcessor 和拦截器注解处理器 InterceptorProcessor ,它们的原理和 RouteProcessor 是一样的。

当我们调用 ARouter 的 build() 方法后,会获取到一个 Postcard 对象,我们调用的 navigation() 方法就是 Postcard 的 navigation() 方法,Postcard 的 navigation() 方法会调用到 _ARoute 的 navigation() 方法中,在这方法中,首先会处理预处理服务,然后会让 LogisticsCenter 填充 Postcard 中的信息,如果 LogisticsCenter 没有找到对应的路由信息的话,就会走降级策略的逻辑,如果 LogisticsCenter 找到对应的路由信息的话,就会判断是不是走绿色通道,如果不走绿色通道的话就由拦截器链决定要不要跳转。如果走绿色通道的话,就直接按 Fragment 和 Activity 等不同的类型进行跳转,在跳转完成后,如果设置了跳转回调, LogisticsCenter 就会调用这个回调。

预处理服务具体就是一个 PretreatmentService 接口,只要定义一个实现了这个接口的类,并给这个类加一个 @Route 注解就可以使用了,预处理服务的作用,是做一些跳转的时候,在加载路由表前的判断。

降级策略的作用是跳转路由的信息缺失的时候,要做的事情,比如说给用户弹一个错误提示或记录错误日志等,降级策略对应的是一个 DegradeService 接口,定义一个实现这个接口的类,并添加上 @Route 注解就可以使用降级策略了。

绿色通道的作用就是判断要不要走拦截器链,比如说我们定义了一个登陆拦截器,但是某个页面不需要做这个判断,就可以走绿色通道,走绿色通道只要在调用 build() 方法后调用 greenChannel() 方法就可以了。

拦截器具体就是一个添加了 @Interceptor 注解并实现了 IInterceptor 接口的类,通过拦截器我们能做一些类似登录态判断等逻辑。

跳转回调具体就是一个传到 navigation() 方法中的 NavigationCallback 接口或 NavCallback 抽象类。

ARouter 生成路由表的方式有两种,一种是运行时反射,另一种是编译时插入

在 ARouter 的 init() 方法中会调用到 LogisticsCenter 的 init() 方法,LogisticsCenter 的 init() 方法会根据 registerByPlugin 的值判断路由表是否已经在编译时插入,如果不是的话,就通过运行时反射注册路由表的信息。

运行时反射就是在 LogisticsCenter 的 init() 方法中,通过 ClassUtils 加载 dex 文件中的 Class 信息,然后再通过反射初始化这些类,并保存到仓库 Warehouse 中。

Dex 文件是 Android 平台的可执行文件,类似于 Windows 中的 exec 文件,每个 APK 安装包中都有 dex 文件,dex 文件中包含了 app 的所有源码,反编译后能看到对应的 java 源码。

编译时插入就是由 RegisterTransformJar 文件中读取路由表的信息。 RegisterTransform 继承了 Transform 类,Transform 是 Android 官方提供的用来修改 class 等资源的 API ,每个 Transform 都是一个 Gradle 任务,能读取和处理 jar、aar 和 resource 等资源,用户自定义的 Transform 会插在 Transform 队列的最前面。

Transform API 可以做很多的事情,比如在所有的 class 文件中插桩,做 UI 、内存和网络方面的性能监控。还可以通过修改某个第三方库的 class 文件的内容调整它的逻辑。还可以在 Log 中插入当前代码行数,这样更容易定位问题。还可以对任何类进行动态代理。还可以实现打印出某个方法的入参和出参的代码。

在java中使用SPI创建可扩展的应用程序

简介

什么是可扩展的应用程序呢?可扩展的意思是不需要修改原始代码,就可以扩展应用程序的功能。我们将应用程序做成插件或者模块。

这样可以在不修改原应用的基础上,对系统功能进行升级或者定制化。

SPI简介

SPI的全称是Java Service Provider Interface。是java提供的一种服务发现的机制。

通过遵循相应的规则编写应用程序之后,就可以使用ServiceLoader来加载相应的服务了。

SPI的实现主要分为4个部分:

Service Provider Interface: SPI是一个interface或者是抽象类,其中定义了我们需要扩展实现的功能。

Service Providers:这是SPI的具体实现,提供了具体的实现功能

SPI Configuration File:SPI的配置文件,通过在配置文件我们来配置相关的SPI发现信息。

ServiceLoader: ServiceLoader是用来加载和发现服务的java类,并提供了很多有用的方法。

Android-使用@AutoService实现spi
深入理解SPI机制
Android组件化开发之SPI
Java基础之SPI机制