Administrator
发布于 2026-08-25 / 19 阅读
0
0

系列文章《Android 工程师的 100 篇进阶笔记》第 23 篇:Android 模块化:Feature Module、Dynamic Delivery 与 App Bundle

项目越大,构建越慢,耦合越重。模块化的目的不是炫技,是为了让团队能并行开发、独立测试、快速构建。


一、模块化的三种粒度

粒度

划分方式

适用阶段

分层模块

app / data / domain / presentation

中小型项目

功能模块

feature-login / feature-home / feature-settings

中大型项目

混合

分层 + 功能交叉

大型团队

常见分层:

  • app:Application、导航、依赖注入

  • feature:xxx:具体业务功能

  • core:common:公共工具、扩展

  • core:network:网络层

  • core:datastore:数据存储


二、Feature Module 的依赖方向

// feature:home 的 build.gradle.kts
dependencies {
    implementation(project(":core:common"))
    implementation(project(":core:network"))
    implementation(project(":feature:detail")) // 直接依赖其他 feature,不推荐
}

更好的做法是反向依赖:

  • Feature 只依赖 core 模块

  • 模块间通信通过路由或事件总线

  • app 模块负责把 feature 拼起来

// 用接口解耦
interface HomeNavigator {
    fun openDetail(itemId: String)
}

三、Dynamic Feature Module

// build.gradle.kts of feature:video
dynamicFeature = true
// app 模块的 build.gradle.kts
android {
    dynamicFeatures += setOf(":feature:video", ":feature:ar")
}

动态模块按需下载,适合:

  • 大体积资源,如 AR、视频特效

  • 不常用功能,如高级设置、企业版功能

  • 地区/语言包


四、App Bundle 与 Dynamic Delivery

上传 Google Play 时用 AAB 格式,Play 会根据设备 ABI、语言、屏幕密度动态分发 APK。

./gradlew bundleRelease

结合 Dynamic Feature,用户第一次安装只下载基础包,后续按需下载功能模块。


五、模块化常见坑

  1. 循环依赖:feature A 依赖 feature B,B 又依赖 A。用接口或路由解耦。

  2. 构建变慢:模块数太多时,gradle 配置时间会增加。用 convention plugin 统一配置。

  3. 资源冲突:模块间同名资源会覆盖。命名规范加前缀。

  4. 导航复杂:多模块间页面跳转用 DeepLink 或 Navigation Component 的 include。


小结

  1. 模块化先按功能拆,再按需分层

  2. Feature 模块之间不要直接依赖,用接口/路由

  3. Dynamic Feature 适合大体积、低频功能

  4. App Bundle 能减小用户实际下载体积

下一篇,我们进入工程质量:Android 测试金字塔与测试策略。


参考阅读

引用链接

[1]Android 模块化指南: https://developer.android.com/topic/modularization

[2]Dynamic Feature Modules: https://developer.android.com/guide/playcore/feature-delivery


评论