Android 搭建模块化项目流程及建议

Android 搭建模块化项目流程及建议

搭建模块化项目会遇到的几个问题

  • 独立模块和组合
  • 第三方库依赖管理
  • 模块间的跳转
  • 模块之间的共性配置
  • 资源文件命名规范
  • Debug 和 Release 源代码配置
  • 模块初始化管理

项目环境:

yaml 复制代码
Android Studio Meerkat Feature Drop | 2024.3.2
Build #AI-243.25659.59.2432.13423653, built on April 30, 2025
Runtime version: 21.0.6+-13368085-b895.109 amd64

独立模块和组合

  1. 在全局配置文件中定义 isRelease

通常可以在项目的 gradle.properties 或一个独立的 gradle 配置文件中定义变量,例如

ini 复制代码
# gradle.properties
isRelease=true

或者通过 ext 在项目级 build.gradle 中定义:

ini 复制代码
// Project-level build.gradle
ext {
    isRelease = true

}

如果是放在新建的 .gradle 文件中,需要在根 build.gradle 文件中引用,其他地方才能正常引用

scss 复制代码
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.kotlin.android) apply false
    alias(libs.plugins.android.library) apply false
    alias(libs.plugins.hilt.android) apply false
}
// 添加引用
apply from: 'env.gradle'
  1. 动态切换 Module 类型

修改当前模块的 build.gradle 文件,根据 isRelease 的值决定使用 com.android.application 插件还是 com.android.library 插件

scss 复制代码
// 修改前
plugins {
    alias(libs.plugins.kotlin.android)
    alias(libs.plugins.android.library)
}
// 修改后
plugins {
    alias(libs.plugins.kotlin.android)
}
//  apply plugin 或者  apply { plugin } 方式都可以
if (isRelease){
    apply plugin:  'com.android.application'
}else{
    apply {  plugin 'com.android.library'}
}

改完是否为 library 还是 application 后,再改 android#defaultConfig 中是否含有 applicationId 属性

arduino 复制代码
        if  (!isRelease){
            applicationId "com.zqautomotive.service"
            targetSdk 35
            versionCode 1
            versionName "1.0"
        }
        minSdk 24

最后在主 APP 中修改

scss 复制代码
    if (isRelease) {
        // 当 service 为 library 时才引入
        implementation project(':service')
    }

第三方库依赖管理

Android 目前是以 libs.versions.toml 文件来管理依赖库

模块间跳转

可以采用阿里的路由框架 ARouter 或反射获取到 Class 后, startActivity 进行跳转

模块间共性配置

在多模块间很多配置都是相同的,可以提取到一个 gradle 文件中

arduino 复制代码
plugins {
    alias(libs.plugins.android.library)
    alias(libs.plugins.kotlin.android)
}

android {
    namespace 'com.zqautomotive.usb'
    compileSdk 35

    defaultConfig {
        minSdk 24

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = '11'
    }
}

dependencies {

    implementation libs.androidx.core.ktx
    implementation libs.androidx.appcompat
    implementation libs.material
    testImplementation libs.junit
    androidTestImplementation libs.androidx.junit
    androidTestImplementation libs.androidx.espresso.core
}

比如上面的配置,除了 namespace不同其他的都是相同配置,提取到 app.gradle 中,但不能有 plugins 标签,该标签只出现在项目级 build.gradle 中,其他的不变。

在模块间引用

csharp 复制代码
plugins {
    alias(libs.plugins.android.library)
    alias(libs.plugins.kotlin.android)
}
// 添加共性配置
apply from: '../app.gradle'

android {
    // 保留 namespace 
    namespace 'com.zqautomotive.usb'
}

dependencies {
    // 如果有单独需要的依赖,添加即可

}

资源文件命名规范

在不同的 model 中,使用命名前缀

arduino 复制代码
android {
    // 资源前缀
    resourcePrefix  'usb_'
}

Debug 和 Release 源代码配置

在 android {} 下配置过滤

arduino 复制代码
    sourceSets {
        main {
            if (isRelease){
                 // 任意路径下包含 debug 目录下的文件都会过滤掉
                 java.exclude '**/debug/**'
            }
        }
    }

多模块初始化管理

在 base 中提供一个中间接口

kotlin 复制代码
class ModuleMediator {

    interface AppInitial {
        fun init(app: Application)
    }

    fun init(app: Application) {
        val appclasses = arrayOf(
            "com.zqautomotive.service.App",
            "com.zqautomotive.usb.App",
            "com.zqautomotive.bluetooth.App",
        )
        for (className in appclasses) {
            try {
                val clazz = Class.forName(className)
                val instance = clazz.newInstance() as AppInitial
                instance.init(app)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}

其他模块 APP 实现 ModuleMediator.AppInitial 接口即可

相关推荐
拓端研究室31 分钟前
专题:2025医药生物行业趋势与投融资研究报告|附90+份报告PDF、原数据表汇总下载
android·开发语言·kotlin
小鱼人爱编程1 小时前
当上组长一年里,我保住了俩下属
android·前端·后端
2501_916013741 小时前
移动端 WebView 调试实战,多平台行为差异排查与统一调试流程
android·ios·小程序·https·uni-app·iphone·webview
IT闫1 小时前
《深入剖析Kafka分布式消息队列架构奥秘》之Kafka基本知识介绍
分布式·架构·kafka
zzywxc7874 小时前
编程算法在金融、医疗、教育、制造业的落地应用。
人工智能·深度学习·算法·机器学习·金融·架构·开源
亿道电子Emdoor5 小时前
【ARM】ARM架构的发展和相关架构
arm开发·架构·arm
liosen5 小时前
【安卓笔记】OOM与内存优化
android·oom·内存优化·内存分析命令·内存分析工具
猿小蔡-Cool9 小时前
Android ADB命令之内存统计与分析
android·adb
Monkey-旭10 小时前
Android Handler 完全指南
android·java·handler
你的人类朋友11 小时前
❤️‍🔥BFF架构版的hello world
前端·后端·架构