# Booster 架构概述

# Booster 的架构设计

可扩展性是 Booster 架构的核心需求,通过功能模块化,让功能开发相对更独立,也方便功能的测试和灰度验证,除此之外,还要解决这些问题:

  1. 如何让模块的开发变得更容易?
  2. 当功能模块足够多时,如何保证构建的性能?
  3. 如何解决开源协议冲突的问题?

为了能很好的解决这些问题,最终 Booster 的架构被设计成如下图所示:

Booster架构

# 如何实现可扩展?

为了实现功能模块的动态发现与加载,Booster 以 SPI (Service Provider Interface) 为基础,通过 Google AutoService 简化了 SPI 的配置,在 Booster 中提供了两大类 SPI:

# 如何让开发变得更容易?

在开发体验和便利性上,Booster 主要做了这些事情:

  1. 抽象 Transform 过程,直接将解析好的 class 文件结构暴露给开发者;
  2. TransformGradle 解耦,在非 Gradle 工程中同样可以复用 BoosterTransformer
  3. 通过 VariantProcessor 解决注入外部库的依赖问题,使得大规模字节码注入成为可能;
  4. AGP 3.0 开始,依次对 AGP 的每个版本进行兼容性适配,并抽象出通用的 Android Gradle API,使得开发者不用关心 AGP 各版本间的差异;
  5. 提供了一系列实用的工具类库,为功能模块开发提升效率;

# 如何保证构建的性能?

  1. 支持增量构建

    无论是 Transform 还是其它的 Task,都支持增量构建。

  2. 一次文件系统 I/O

    Booster 的源码中可以看到,整个 Transform 过程只涉及到一次读写文件系统,所有的 Transformer 都是访问内存中的 Class 结构

  3. Transformer Pipeline 与并行 Transformer

    整个 Transform 的过程以单个 JAR 或目录为粒度进行流式处理,各个 Transformer Pipeline 并行执行,最大限度利用 CPU 资源。

  4. 并行写磁盘

    通过并行方式将 class 写回 JAR 中。

  5. 性能测试

    通过 JMH 对多个技术方案进行 benchmark 测试,选择性能最优的方案,详见:booster-benchmark

# 如何解决开源协议冲突?

Booster 中,除了 Task SPITransform SPI 以外,还提供了一种 SPI —— Command SPI

Command SPI 主要是为了解决在 Apache License 的协议许可下使用 GPL License 的开源软件,如:pngquant 采用了 GPL License 开源许可,直接在项目中使用会有一定的法律风险,所以 Booster 的做法是将部分抽象出来,以 SPI 的形式在运行时动态发现和加载 Command SPI 的实现,这样,既能保证开源许可的合法性,又能使用优秀的 GPL 开源软件。