1.1 按需加载模块基本概念

按需加载(On-Demand Delivery)是 Android 为解决安装包膨胀而推出的核心策略,它允许应用在运行时动态下载之前未包含在基础 APK 中的功能模块。本章将系统梳理支撑这一能力的三项关键技术:Android App Bundle、Dynamic Feature 以及 SplitInstall 库,并辨析按需加载与延迟加载的本质区别。

按需加载核心概念架构 Android App Bundle Dynamic Feature SplitInstall 库 按需加载 延迟加载 用户操作触发 → 运行时下载并安装 → 首次启动体验 显著减小基础安装包体积

1.1.1 Android App Bundle

Android App Bundle(AAB)是 Google 推荐的官方发布格式,它将应用拆分为多个分发单元(Split),而不是单个巨型 APK。

  • 基础模块(Base Module):包含核心代码、资源和清单,是运行时必须的部分。
  • 功能模块(Dynamic Feature Module):按需分发的独立模块,仅在用户触发时才下载。
  • 配置 APK(Configuration APKs):针对屏幕密度、CPU 架构等自动生成的优化包。
💡 实践要点:Google Play 商店在下载时仅向设备推送最匹配的配置 APK + 基础模块,从而平均减少约 15%–20% 的下载量。

1.1.2 Dynamic Feature 模块

Dynamic Feature 是 AAB 生态中的按需分发单元。开发者可以在 build.gradle 中声明该模块的安装时机:

安装时机行为说明
install-time随基础模块一起安装,同传统 APK 行为
on-demand用户主动触发时加载,这是按需加载的典型模式
conditional仅在满足特定条件(如系统版本、地区)时安装
关键配置示例(位于 Dynamic Feature 模块的 build.gradle):
android {
    dynamicFeatures = [":cameralens", ":ar_module"]

    defaultConfig {
        // 使用 split 分发
        splits {
            abi { enable true; reset(); include "x86", "arm64-v8a" }
        }
    }
}

dependencies {
    implementation "com.google.android.play:core:1.10.3"
    // 注意:play-core 必须添加到基础模块和每个 DF 模块
}

1.1.3 SplitInstall 库

SplitInstall 是 Google Play Core 库提供的客户端 API,负责在 Android 设备上下载、安装和管理来自 Google Play 的动态功能模块。核心能力包括:

  • 请求安装:通过 SplitInstallManager 发起按需下载。
  • 进度监听:支持回调 onInstallStateUpdate 获取下载/安装状态。
  • 模块卸载:通过 deferredUninstall() 清理不再需要的模块。
  • 错误处理:包括网络失败、存储不足、模块未发布等场景。
⚠️ SplitInstall 仅在通过 Google Play 分发的 AAB 包上生效。侧载或非 Play 商店安装无法使用该 API。

1.1.4 按需加载 vs 延迟加载

两种策略虽然都涉及“晚加载”,但机制完全不同。下表从多个维度进行对比:

维度按需加载延迟加载
触发时机用户显式操作(点击按钮、进入页面)应用启动或空闲时段的后台预加载
是否依赖 Play 商店是,通过 SplitInstall API 请求Google Play否,模块已存在于基础 APK 中
网络需求需要网络下载模块不需要,从本地存储加载
安装包体积影响大幅减少首次安装体积不减少,模块始终在包内
用户体验首次使用需等待下载完成几乎零延迟,但占用预加载资源
典型场景付费功能、AR 模块、语音包首页数据预取、子页面预初始化

在实际项目中,两者通常配合使用:按需加载解决“不该提前打包”的问题,延迟加载优化“已经打包但暂不需要”的资源。

代码示意:使用 SplitInstallManager 发起按需下载
// 早期初始化(onCreate 中获取 Manager)
SplitInstallManager manager =
    SplitInstallManagerFactory.create(context);

// 构建要安装的模块名称列表
SplitInstallRequest request =
    SplitInstallRequest.newBuilder()
        .addModule("cameralens")
        .addModule("filter_pack")
        .build();

// 异步发起下载
manager.startInstall(request)
    .addOnSuccessListener(sessionId -> Log.i("DF", "安装启动: " + sessionId))
    .addOnFailureListener(e -> {
        // 处理常见错误:网络、存储、模块未定义等
        if (e instanceof SplitInstallException) {
            int errorCode = ((SplitInstallException) e).getErrorCode();
            // 根据 errorCode 做降级处理
        }
    });

以上代码展示了按需加载的核心调用模式:通过 Play Core 库提供的 API,开发者可以精确控制模块的下载时机,而无需在基础 APK 中打包这些功能。