ARouter 原理浅析

ARouter是阿里巴巴开源的路由框架:https://github.com/alibaba/ARouter

ARouter

ARouter 是通过注解的方式结合android提供的启动Activity的API实现页面的跳转及参数的传递的。

ARouter 提供三种注解类型:

@Route:注解跳转页面或是需要实例化的的类

@Interceptor:注解自定义拦截器

@AutoWired:注解需要自动赋值的成员变量

ARouter的工作过程可以分为三个部分:

  1. 编译期通过注解处理器生成相关的中间类;

  2. 程序启动时初始化ARouter;

  3. 通过ARouter实例解析路由地址实现页面跳转及参数专递。

1.ARouter 是在编译期通过注解处理器扫描被注解的元素,然后根据不同类型分别处理。

在编译期会生成几个关键的中间类:

(1)IRouteRoot接口的实现类:

每个moudle下都会生成一个该类型的实现类,通过module名来区分的,该类的作用是将每个module下所有的分组按照组名和对应分组的实现类(IRouteGroup接口的实现类)的Class对象做一个映射,然后保存在一个全局的groupIndex的map表中。

(2)IInterceptorGroup接口的实现类:该类的作用是将各个module下的自定义的interceptor 按照优先级和interceptor的Class对象做一个映射,然后保存在一个全局的interceptorIndex的map表中。

(3)IProviderGroup接口的实现类:该类的作用的是将项目中自定义的提供序列化功能的类的相关信息以RouteMeta类的对象保存在全局的providerIndex的map表中。

(4)IRouteGroup接口的实现类:该类的作用是将每个分组下所有route地址对应页面的相关信息分别封装在RouteMeta对象中,然后将route地址与对应的RouteMeta对象做一个映射保存在全局的routes map表中。

2.程序启动时初始化ARouter。初始化时ARouter的init()方法首先会在app内查找指定package包目录下所有class类文件,然后在这些class中对三种类型的class进行初始化:

(1)是IRouter接口的实现类;

(2)是IInterceptorGroup接口的实现类;

(3)是IProviderGroup的实现类;

都是通过反射的方式进行实例化并调用loadInto()方法进行初始化操作。

3.ARouter的使用:在使用ARouter的时候是通过ARouter.getInstance().build("route").withString(param)...navigation().这种方式来调用的。

首先获取ARouter的一个单例调用build()方法传入路由地址,build方法会根据路由地址获取所属的组名,并把路由地址和组名等信息封装在PostCard类型(继承RouteMeta类型的)的对象中返回,navigation()方法最后会调用到ARouter的navigation()方法,这个方法中会先做一些前置的工作,主要是通过调用LogisticsCenter类的静态方法completion()来完成的,这个方法中会先通过路由地址在全局的routes表中查找对应页面信息是否存在,如果存在就继续后面的逻辑,如果不存在也就是第一次遇到该分组的路由时,会继续根据组名在全局的groupIndex表中查找对应的分组实现类的Class对象(一般情况下只要初始化成功了,这个Class对象就一定会存在的,如果不存在就会抛异常),然后通过反射的方式创建该类的实例并调用loadInto()方法将该组下所有的路由地址与对应页面的信息做一个映射保存在全局的routes表中,再次调用completion()方法,此时路由地址对应的页面信息有了,接下来会把对应的页面信息存到pastcard对象中,然后根据postcard中存储的页面类型进行判断,这里判断了两种类型:IProvider类型和Fragment类型,如果是Provider类型 会获取该类的Class对象通过反射的方式创建一个实例并存储在postcard的provider变量中,同时将该route地址对应的Class对象与该实例做一个映射保存在全局的providers的map表中,并设置其绿色通道标志位;如果是Fragment类型则设置绿色通道标志位即可。然后返回navigation()继续执行,接下来会根据postcard中存储的类型分别进行处理:

(1)如果是Activity类型的话,会创建一个intent设置设置相关参数及flag位,然后通过startActivity()方式启动目标页面;

(2)如果是Provider类型 就直接返回postcard中provider变量;

(3)如果是broadcastRecevier,service,contentProvider及fragment类型时,则使用该类的Class对象通过反射的方式创建一个实例,如果该实例是v4或是app包中的fragment的话则强转为对应类型,最后返回该实例;其他类型则返回null。

你可能感兴趣的:(android)