4. 动态功能模块创建:新建module、build.gradle中的dist:delivery、dist:instant、dist:condition属性
动态功能模块(Dynamic Feature Module)是 Android App Bundle 实现按需交付的核心单元。一个 AAB 可以包含一个基础模块(base)和零个或多个动态功能模块。本章将演示如何从零创建一个动态功能模块,并解析 build.gradle 中 dist:delivery、dist:instant 与 dist:condition 三个关键属性的作用与配置方法。
4.1 新建动态功能模块
在 Android Studio 中,通过菜单 File → New → New Module,选择 Dynamic Feature Module 模板。填写模块名称(例如 feature_video)、包名、最小 SDK 版本以及基础模块依赖。AS 会自动生成以下关键文件:
src/main/AndroidManifest.xml—— 包含<dist:module>标签src/main/java/...—— 业务代码build.gradle—— 动态功能模块的 Gradle 配置
手动创建时,需确保在项目根目录的 settings.gradle 中包含该模块:
include ':app', ':feature_video'
:app)必须将 dynamicFeatures 属性指向动态功能模块,否则打包时会被忽略。
4.2 build.gradle 核心配置:dist 命名空间
动态功能模块的 build.gradle 必须声明 android.dynamicFeatures(在基础模块的 build.gradle 中)以及本模块内部的 dist 属性。以下是完整配置示例:
// 基础模块 :app 的 build.gradle
android {
...
dynamicFeatures = [':feature_video']
}
// 动态功能模块 :feature_video 的 build.gradle
apply plugin: 'com.android.dynamic-feature'
android {
compileSdk 33
defaultConfig {
minSdk 21
}
// 关键区域:dist 配置块
dist {
delivery {
// 安装时分发
installTime
}
instant {
enabled true
}
conditions {
// 仅在设备拥有摄像头时下载
deviceFeature "android.hardware.camera"
// 国家或地区条件
countryCode "US", "DE"
// 应用版本范围
minSdkVersion 21
maxSdkVersion 33
}
}
}
dependencies {
implementation project(':app')
// 其他依赖
}
4.3 属性详解
| 属性 | 作用 | 可选值 |
|---|---|---|
dist:delivery |
定义模块的分发时机 | installTime(安装时一起下载)onDemand(按需下载)/* 空 */(默认 installTime) |
dist:instant |
是否支持免安装体验(Instant App) | enabled true/false |
dist:condition |
条件分发:按设备特征、国家、API 等级等触发下载 | deviceFeature、countryCode、minSdkVersion、maxSdkVersion |
dist:delivery = installTime 的模块会随基础模块一起打包进 universal APK,但不会出现在按需下载的动态功能列表中。如果希望模块只在特定条件下下载,必须使用 onDemand 并配合 conditions。
4.4 动态交付条件组合逻辑
条件分发支持多个条件同时配置,默认逻辑为 AND(所有条件满足时才触发分发)。例如上例中,模块仅在 API 21~33、设备有摄像头、且国家为 US 或 DE 时才会被下载。若需要 OR 逻辑,需在 Play Console 中使用高级配置。
4.5 内部结构图:动态功能模块声明流程
4.6 模块分割规则与注意事项
- 资源与代码隔离:每个动态功能模块拥有独立的
src/main/res和src/main/java,模块之间不能直接引用资源 ID,必须通过基础模块暴露接口或使用R.*全路径引用。 - MinSdk 同步:动态模块的
minSdk必须 >= 基础模块的minSdk。 - 清单合并:
AndroidManifest.xml中的<dist:module>标签是必需的,且dist:onDemand属性必须与 Gradle 中的delivery配置一致。 - 命名规范:模块名称建议使用小写+下划线,避免使用驼峰,否则在 Play Console 中可能出现识别问题。
onDemand 分发以减小初始安装包体积;对于核心功能(如登录、首页),使用 installTime 确保用户立即拥有。
4.7 验证模块声明
完成配置后,执行 ./gradlew :bundleRelease 生成 AAB 文件。使用 bundletool 查看模块信息:
java -jar bundletool-all.jar dump manifest --bundle app/build/outputs/bundle/release/app-release.aab
输出中应包含类似以下内容:
<dist:module dist:name="feature_video" dist:onDemand="false">
<dist:delivery>
<dist:install-time/>
</dist:delivery>
<dist:instant>
<dist:enabled>true</dist:enabled>
</dist:instant>
<dist:conditions>
<dist:device-feature name="android.hardware.camera"/>
<dist:country-code code="US"/>
<dist:country-code code="DE"/>
</dist:conditions>
</dist:module>
若未看到对应模块,说明配置缺失或基础模块的 dynamicFeatures 未正确指向。
4.8 常见错误及解决
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| Gradle 构建失败:Module not specified | settings.gradle 缺少模块引用 |
添加 include ':feature_video' |
| 无法生成 AAB:Dynamic feature without base | 模块 build.gradle 未 apply com.android.dynamic-feature |
检查插件声明是否正确 |
| bundletool 输出缺少模块 | 基础模块 dynamicFeatures 未包含该模块 |
在 :app 的 build.gradle 中补全 |
| 按需下载失败:Module not found | dist:delivery 配置为 installTime 导致模块不在按需列表 |
改为 onDemand |
通过以上步骤,你可以成功创建一个满足动态交付条件的 Android 动态功能模块,并在 AAB 打包时精确控制其分发策略。