## 第1章 SplitInstall核心原理:Split APK机制、按需交付、条件下载 ### 1.1 Split APK 机制:单体 APK 的分拆与组合 从 Android 5.0(API 21)开始,Google 引入了 **Split APK** 架构,允许将传统单体 APK 拆分为多个独立的 APK 文件(Base APK + 多个 Split APK)。每个 Split APK 可以包含独立的代码、资源、Native 库或资产(Assets)。 | 对比维度 | 传统单体 APK | Split APK 架构 | |----------|--------------|----------------| | 安装包结构 | 单个 .apk 包含所有内容 | Base APK + 多个 Split APK | | 安装体积 | 一次性下载全部内容 | 仅下载 Base + 用户当前需要的 Split | | 动态下发 | 不支持(需更新全包) | 支持通过 SplitInstall API 按需下发 | | 多模块维护 | 所有功能耦合在一个包内 | 功能模块独立拆分,可单独更新 | **核心机制**:Base APK 包含应用基础生命周期、Manifest 和公共资源;每个 Split APK 对应一个“功能模块”(feature module),拥有独立的命名空间。系统在安装时将所有 Split APK 合并为一个“虚拟”的完整应用,运行时在 same process 内加载,对开发者透明。
关键点:Split APK 不是插件化或热修复,而是 Google Play 官方支持的模块化交付策略。所有 Split APK 都共用同一个 PID 和 Application 实例。
### 1.2 按需交付(On-Demand Delivery) 按需交付是指应用在运行时通过 SplitInstall API 向 Google Play 请求下载并安装特定功能模块,无需用户手动更新整包。典型流程如下: 1. 应用启动时仅加载 Base APK 中的核心功能。 2. 当用户触发一个“未安装模块”的功能(例如首次进入支付页面)时,应用调用 `SplitInstallManager` 发起下载请求。 3. Google Play 服务在后端计算该模块对应的 Split APK,判断条件并开始下载。 4. 下载完成后,Play 服务调用系统安装器将 Split APK 安装到设备,并回调给应用。 5. 应用收到成功回调后,加载模块代码并呈现功能。 **API 示例**:发起一个按需下载请求
SplitInstallManager splitInstallManager = SplitInstallManagerFactory.create(context);
SplitInstallRequest request = SplitInstallRequest.newBuilder()
        .addModule("payment")
        .build();
splitInstallManager.startInstall(request)
        .addOnSuccessListener(sessionId -> {
            Log.d("SplitInstall", "模块 payment 下载启动,sessionId: " + sessionId);
        })
        .addOnFailureListener(exception -> {
            Log.e("SplitInstall", "下载启动失败", exception);
        });
最佳实践:建议在用户即将使用目标功能前预下载(prefetch),通过 deferredInstall 或低优先级后台下载减少等待时间。
### 1.3 条件下载(Conditional Delivery) 条件下载允许开发者根据设备属性、语言、国家、API 级别等条件,在构建时声明模块是否应自动包含。条件在 `build.gradle` 中使用 `distributions` 和 `delivery` 块配置:
android {
    defaultConfig {
        // 启用按需交付
        distribution {
            splitInstallEnabled = true
        }
    }
    dynamicFeatures = [":payment_feature"]
}

// 支付模块的 build.gradle
android {
    defaultConfig {
        versionCode 1
        versionName "1.0"
    }
    // 仅在用户语言为zh且设备为Pixel设备时自动安装
    // (实际使用distributions DSL更常见)
}
**常见的条件类型**: | 条件类型 | DSL 配置 | 示例 | |----------|----------|------| | 设备语言 | `language` | `language "zh", "en"` | | 国家区域 | `country` | `country "US", "JP"` | | 最小 API 级别 | `minSdkVersion` | `minSdkVersion 26` | | 屏幕特征 | `screenDensity` | `hdpi, xhdpi, xxhdpi` | | 硬件特征 | `feature` | `"android.hardware.telephony"` | ### 1.4 核心工作流程图 下图展示了 SplitInstall 从请求到完成的核心流程,包含按需下发和条件校验两个主要分支。 SplitInstall 核心工作流程 SplitInstall 核心工作流程 用户触发模块需求 SplitInstallManager.startInstall() Google Play 检查条件(语言/国家等) 条件匹配? 是 否 模块不可用 通知应用 下载 Split APK 安装到设备 安装成功回调 加载模块 并呈现UI 注意:条件不满足时,应用应提供降级方案或提示用户手动下载 ### 1.5 调试与验证 开发阶段可通过以下方式测试 SplitInstall 流程: - **使用 Play 服务测试工具**:`adb shell am broadcast -a com.google.android.gms.feedback.SPLIT_INSTALL` - **日志过滤**:在 logcat 中过滤 `SplitInstall` 或 `SplitCompat` 查看状态。 - **手动触发条件**:修改模拟器语言或添加 `wearable` 特征模块验证条件下载。
常见误区:SplitInstall 只能在正式签名且通过 Google Play 发行的应用上工作。测试阶段必须使用“Play 内部测试”或“Google Play Console 测试渠道”,不能仅通过 Android Studio 直接运行。
### 1.6 性能与稳定性优化建议 | 优化项 | 说明 | |--------|------| | **预下载模块** | 在应用启动或后台空闲时调用 `deferredInstall` 提前下载高概率模块 | | **重试策略** | 失败时使用指数退避重试,间隔建议 30s、30s、60s、120s…… | | **模块大小控制** | 每个 Split APK 尽量小于 50MB,避免超长安装等待 | | **回退方案** | 条件不满足时提供 WebView 兜底或引导用户手动更新 | 理解 Split APK 机制、按需交付和条件下载是后续章节(如支付模块拆解、API 实战、错误处理)的基础。下面两章将深入 SplitInstall API 的详细使用方法与常见错误场景。