news 2026/6/11 20:40:09

从单体“巨石”到优雅多模块:Android架构进阶必修课

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从单体“巨石”到优雅多模块:Android架构进阶必修课

项目刚起步时,所有代码塞进一个app模块完全没问题。但随着功能越来越多,你会发现:改一行代码要全量编译几分钟、不同团队改同一个模块频繁冲突、想复用某块功能却发现它和一堆东西耦合在一起拆不出来。

这时就该上多模块化(Modularization):把一个巨大的app拆成多个职责清晰、可独立编译、可复用的 module,就像把一栋大楼分成若干独立单元。本文讲清为什么拆、怎么拆、模块间如何通信。


一、为什么要多模块化

收益说明
编译更快只重新编译改动的模块(增量编译 + 并行)
职责清晰每个模块边界明确,强制解耦
可复用通用模块可被多个 App / feature 复用
团队协作不同团队负责不同模块,减少冲突
按需交付配合 Dynamic Feature 实现功能动态下发

经验信号:当全量编译超过几分钟、或多人频繁在同一文件冲突时,就该考虑拆模块了。


二、常见的分层模块策略

一种被广泛采用的分层(参考官方 Now in Android 架构):

:app 应用入口,组装各 feature ├── :feature:home 功能模块(首页) ├── :feature:profile 功能模块(个人中心) ├── :core:ui 通用 UI 组件、主题 ├── :core:data Repository、数据源整合 ├── :core:network 网络层(Retrofit/OkHttp) ├── :core:database 数据库层(Room) ├── :core:model 纯数据模型(无依赖) └── :core:common 工具类、扩展函数

依赖方向规则(关键):

app ──> feature ──> core

永远是上层依赖下层,下层绝不反向依赖上层;feature 模块之间也不互相依赖。


三、模块类型

类型Gradle 插件用途
应用模块com.android.application最终 App,只能有一个入口 app
库模块com.android.libraryfeature/core 模块,产出 aar
纯 Kotlin 模块org.jetbrains.kotlin.jvm无 Android 依赖的逻辑/模型层
Dynamic Featurecom.android.dynamic-feature按需下载的功能模块

:core:model:core:common这类不依赖 Android API 的模块尽量做成纯 Kotlin 模块,编译更快、也能被测试直接用。


四、模块间通信与解耦

模块拆开后,怎么让:feature:home用到:feature:profile的能力,又不直接依赖它?

  1. 接口下沉:把公共接口放到下层:core模块,feature 依赖接口而非实现。
  2. 依赖注入:用 Hilt 在 app 层组装实现,feature 只声明需要什么。
  3. 导航解耦:用 Navigation 的 deep link 跨模块跳转,避免直接引用对方 Activity/Fragment 类。

五、用 Version Catalog 统一依赖

多模块下最怕"各模块依赖版本不一致"。用gradle/libs.versions.toml(Version Catalog)集中管理:

[versions] retrofit = "2.11.0" [libraries] retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
// 任意模块dependencies{implementation(libs.retrofit)}

再配合convention plugins(约定插件)把各模块重复的构建配置抽出来,避免每个build.gradle复制粘贴。


六、apivsimplementation

关键字依赖是否传递给上游
implementation不传递(默认首选,编译更快)
api传递(上游也能用到这个依赖)

默认用implementation。滥用api会让依赖"穿透"多层模块,破坏封装,还会拖慢编译——改一个底层依赖导致一大片模块重编。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 20:37:55

MC9S08GB60A引脚配置与低功耗模式实战解析

1. 项目概述与核心价值对于嵌入式开发者而言,拿到一款新的微控制器(MCU),第一件事往往不是急着写代码,而是先“摸清”它的“脾气”——也就是引脚配置和工作模式。这就像你要指挥一支军队,必须先了解每个士…

作者头像 李华
网站建设 2026/6/11 20:35:53

083、ISP 内部流水线调度:Frame-level vs Line-level 处理的延迟与带宽差异

083、ISP 内部流水线调度:Frame-level vs Line-level 处理的延迟与带宽差异 从一次“花屏”调试说起 去年做某款旗舰机的前摄调试,遇到一个诡异现象:暗光下预览画面每隔几帧会出现一条横向的“撕裂带”,位置不固定,有时在画面顶部,有时在中间。用示波器抓MIPI CSI时钟,…

作者头像 李华
网站建设 2026/6/11 20:33:02

运维的能力——不是会装系统是半夜出事你敢接电话

运维的能力——不是会装系统,是半夜出事你敢接电话 会装Nginx的、会配防火墙的、会搭监控的,都不一定是好运维。好运维只有一个标准:生产环境出事了,你敢不敢接那个凌晨三点的电话。这篇不讲具体命令怎么敲,讲的是运维…

作者头像 李华
网站建设 2026/6/11 20:31:06

深入解析BDM硬件握手协议:ACK脉冲同步与异常处理机制

1. 项目概述:为什么需要深入理解BDM?在嵌入式开发,尤其是汽车电子和工业控制领域,调试器与目标芯片之间的通信可靠性是决定开发效率的关键。当你的代码在飞思卡尔(现恩智浦)MC9S12这类16位微控制器上运行时…

作者头像 李华
网站建设 2026/6/11 20:29:34

PCA9532 I2C LED驱动芯片:从原理到实践的完整指南

1. 项目概述:为什么选择PCA9532这颗芯片?在嵌入式项目里,控制一堆LED灯是再常见不过的需求了。无论是设备状态指示、背光照明,还是简单的装饰灯带,你总得想办法让它们亮起来、暗下去,甚至能呼吸闪烁。最直接…

作者头像 李华