ARouter基本使用及原理分析

本文详细介绍了阿里开源的Android路由框架ARouter,它可助力App组件化改造,实现不同模块Activity间跳转。文中阐述了其原理、基本用法、架构,还深入分析了APT原理、路由表的生成、加载与跳转等内容,对Android开发者有重要参考价值。

作者:愿天深海

ARouter简介

ARouter是阿里开源的一款帮助Android App进行组件化改造的路由框架,是Android平台中对页面和服务提供路由功能的中间件,可以实现在不同模块的Activity之间跳转。

ARouter的特点是灵活性强还能帮助项目解耦。

除了广为人知的Activity跳转之外,ARouter还支持获取Fragment,解耦服务使得跨模块API调用等等

ARouter原理概述

ARouter使用@Route注解,在编译时期通过APT技术生成类文件用于存储path和activityClass的映射关系。

在app进程启动的时候会拿到这些类文件,把里面存储的映射关系数据读到内存里,保存在路由表map中。 在进行路由跳转时,通过ARouter的build()方法传入要到达页面的路由地址,ARouter在路由表中找到路由地址对应的activityClass,然后new Intent(),通过ARouter的withString()方法传入携带参数,内部调用intent.putExtra(),通过ARouter的navigation()跳转,内部调用startActivity(intent)。

这样就实现了在不同模块之间,不相互依赖,却顺利启动对方的Activity。

ARouter基本用法

添加依赖与配置

//注解处理插件
plugins {
    ...
    id 'kotlin-kapt'
}

//注解处理选项
kapt {
    arguments {
        arg("AROUTER_MODULE_NAME", project.getName())
    }
}

//依赖
dependencies {
    // 替换成最新版本, 需要注意的是api要与compiler匹配使用,均使用最新版可以保证兼容
    implementation 'com.alibaba:arouter-api:x.x.x'
    kapt 'com.alibaba:arouter-compiler:x.x.x'
    ...
}

添加注解

// 在支持路由的页面上添加注解(必选)
// 这里的路径需要注意的是至少需要有两级,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
    ...
}

初始化SDK

if (isDebug()) {           // 这两行必须写在init之前,否则这些配置在init过程中将无效
    ARouter.openLog();     // 打印日志
    ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
}
ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化

发起路由操作

// 1. 应用内简单的跳转(通过URL跳转在'进阶用法'中)
ARouter.getInstance().build("/test/activity").navigation();

// 2. 跳转并携带参数
ARouter.getInstance().build("/test/1")
            .withLong("key1", 666L)
            .withString("key3", "888")
            .withObject("key4", new Test("Jack", "Rose"))
            .navigation();

ARouter架构概览

ARouter项目代码结构如上,红框内为最核心的4部分,架构关系如下,

ARouter项目中包含了API、编译器Compiler、插件Gradle Plugin和注解Annotation4 个模块。

API

API 模块由launcher、core、exception、thread、facede、utils和base子模块组成。

  • launcher:包含了启动器 ARouter。
  • core:包含物流中心 LogsticsCenter 和仓库 Warehouse 等类。
  • exception:包含了一些异常类。
  • thread:包含了CancellableCountDownLatch,ARouter 的拦截器链是放在子线程中执行的,就用到了它。
  • facede:包含了导航回调 NavigationCallback 和 拦截器IInterceptor 等接口。
  • utils:包含了 ARouter 自定义的日志打印器等工具类。
  • base:只有一个用于保存拦截器的 UnitqueKeyTreeMap。

Compiler

Compiler 模块用于生成路由表,@Autowired、@Interceptor 和 @Route 注解对应的注解处理器分别是 AutowiredProcessor、InterceptorProcessor 以及 RouteProcessor ,都在 Compiler 中。

Register Plugin

Register Plugin 模块包含了注册代码生成器 RegisterCodeGenerator 和 RegisterTransform,如果使用了ARouter的路由表加载插件,那这个路由表就会由Register插件加载。

Annotaion

Annotaion模块比较简单,只包含了一些注解和枚举类。

APT原理

ARouter的使用非常方便,得益于APT技术。APT的作用是在编译阶段扫描并处理代码中的注解,然后根据注解输出Java文件。

ARouter为了方便实现注解处理器还额外用了两个库。

  • JavaPoet,提供了调用对象方法的方式生成需要的代码,而不再需要人为地用StringBuilder去拼接代码,再使用IO写入文件。
  • Auto-Service,提供了简便的方式去注册APT,避免了原本繁琐的注册步骤。

@Route

@Route的定义:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route {

    /**
     * Path of route
     */
    String path();
    ......
}
  • @Target({ElementType.TYPE}):表示这个注解是修饰类的
  • @Retention(RetentionPolicy.CLASS):表示需要保留到编译时

使用该注解时有一个主要的参数path:

// 在支持路由的页面上添加注解(必选)
// 这里的路径需要注意的是至少需要有两级,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
    ...
}

这样编译时能获取到@Route所注解的类,并且能获取到path路径。

RouteProcessor

RouteProcessor是@Route注解对应的注解处理器。

@AutoService(Processor.class)
@SupportedAnnotationTypes({ANNOTATION_TYPE_ROUTE, ANNOTATION_TYPE_AUTOWIRED})
public class RouteProcessor extends BaseProcessor 
  • Auto-Service这个库为Processor完成了自动注册.
  • @SupportedAnnotationTypes({ANNOTATION_TYPE_ROUTE, ANNOTATION_TYPE_AUTOWIRED}):表明了当前Processor是处理哪些注释的。

RouteProcessor继承于BaseProcessor,在init方法中获取到了每个模块的moduleName。

        // Attempt to get user configuration [moduleName]
        Map<String, String> options = processingEnv.getOptions();
        if (MapUtils.isNotEmpty(options)) {
            moduleName = options.get(KEY_MODULE_NAME);
            generateDoc = VALUE_ENABLE.equals(options.get(KEY_GENERATE_DOC_NAME));
        }

RouteProcessor的process方法是对注解处理的地方,它直接获取了所有使用@Route注解的元素。

Set<? extends Element> routeElements = roundEnv.getElementsAnnotatedWith(Route.class);

拿到使用注解的元素后就会进入this.parseRoutes(routeElements)方法。这个方法使用JavaPoet生成Java文件。如果不用这个库也可以使用StringBuilder去写Java文件的内容。

IRouteGroup

先来看一下RouteProcessor生

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值