Android模块化管理

项目架构,从来都是按照实际需求情况演进的

<壹> app模块

在组件化/模块化架构中,app 模块作为宿主(主壳)是非常关键的设计。它的作用远远不止是一个简单的启动入口,而是一个精心设计的架构核心。让我详细解释它的作用和用意:

一、核心作用

1. 应用的统一入口

kotlin 复制代码
// app/build.gradle
apply plugin: 'com.android.application'
  • 这是唯一拥有 application 插件的模块
  • 包含应用的 Application 类和启动 Activity
  • 定义了应用的包名、版本号、签名等元信息

2. 组件/模块的装配中心

kotlin 复制代码
// app/build.gradle
dependencies {
    implementation project(':core')
    implementation project(':feature-ui')
    implementation project(':feature-arch')
    implementation project(':feature-performance')
    // ... 按需集成其他模块
}
  • 像一个"主板",把所有功能模块像"插卡"一样集成在一起
  • 决定哪些模块被包含在最终APK中

3. 全局配置和管理

kotlin 复制代码
// app/src/main/java/com/example/MyApplication.kt
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // 全局初始化
        initRouter()      // 路由框架初始化
        initCrashHandler() // 全局异常处理
        initPerformance()  // 性能监控初始化
        initLogging()      // 日志系统初始化
        
        // 按需延迟初始化某些模块
        initModulesLazily()
    }
}

4. 路由和导航中枢

ARouter在单activity多compose的场景,不适用。

TheRouter未确定。

kotlin 复制代码
// app模块负责配置全局导航,或者
object AppRouter {
    fun setup() {
        ARouter.init(application)
        ARouter.openDebug()
        // 添加全局拦截器(如登录检查)
        ARouter.getInstance().addInterceptor(LoginInterceptor())
    }
}

// 壳中的MainActivity通常作为容器
class MainActivity : BaseActivity() {
    // 可能只是一个简单的容器,实际内容由各模块提供
}

二、架构用意

1. 单一职责原则

  • 各业务模块:专注于自己的功能实现,不关心如何被集成
  • 宿主模块:专注于组装和调度,不包含具体业务逻辑

2. 解耦的关键设计

text 复制代码
传统单体应用:
app(包含所有代码和逻辑)
|
├── ui包
├── network包  
├── database包
└── ...

组件化架构:
app(空壳,仅集成和调度)
|
├── core(基础库)
├── feature-A(独立业务组件,可单独运行)
├── feature-B(独立业务组件,可单独运行)
└── ...
  • 业务模块之间没有直接依赖,都只依赖 core 模块
  • 模块间通信通过接口/路由,而不是直接引用

3. 灵活的动态配置

groovy 复制代码
// 可以灵活控制哪些模块被包含
dependencies {
    // 基础模块,始终包含
    implementation project(':core')
    
    // 按需引入的特性模块
    if (isFeatureEnabled('performance')) {
        implementation project(':feature-performance')
    }
    
    if (isFeatureEnabled('custom_ui')) {
        implementation project(':feature-ui')
    }
    
    // 调试专用模块,只包含在debug版本
    debugImplementation project(':debug-tools')
}

4. 独立调试与集成发布的切换

groovy 复制代码
// 在业务模块中,可以这样配置
// feature-ui/build.gradle
if (isRunAlone()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

android {
    defaultConfig {
        if (isRunAlone()) {
            // 独立运行时需要自己的ApplicationId
            applicationId "com.example.feature.ui"
        }
    }
    
    sourceSets {
        main {
            // 独立运行时使用自己的AndroidManifest
            if (isRunAlone()) {
                manifest.srcFile 'src/main/runAlone/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }
}
相关推荐
jearry几秒前
WebView2 原生拖放的桥接之道:拆解 yyzTools 的 drop-zone.js
前端·c++
一位正在转型AI全栈的前端工程师2 分钟前
AI 全栈学习之旅 -Week 11:从 CLI 到浏览器:用 FastAPI、SSE 和 Vue 3 做一个可审核的 ReAct Agent
前端·python
10share5 分钟前
我为什么用 React 重写了一个 VitePress
前端·react.js
计算机魔术师8 分钟前
GPT-6 Astra 发布后,Sebastian Raschka 解析 looped transformer 与隐藏推理链传闻
前端
不可能片场14 分钟前
Electron 退化成 node:一个环境变量的锅
前端·electron
楚楚河河15 分钟前
js 变量声明
前端
Cicada12823 分钟前
Web 服务器怎么选
运维·服务器·前端
不可能片场25 分钟前
接口返回 200 不代表活着:catch-all 路由的陷阱
前端·electron
用户9210802628630 分钟前
Cookie 和 Token,到底谁在负责登录态
前端
阳火锅32 分钟前
2025,记住这一年!它是古法编程的最后一年。
前端·javascript·面试