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 接口即可

相关推荐
p***c9492 小时前
后端在微服务中的服务网关
微服务·云原生·架构
Bervin121384 小时前
Flutter Android环境的搭建
android·flutter
summer_west_fish8 小时前
单体VS微服务:架构选择实战指南
java·微服务·架构
7***u2169 小时前
显卡(Graphics Processing Unit,GPU)架构详细解读
大数据·网络·架构
p***q789 小时前
电池管理系统(BMS)架构详细解析:原理与器件选型指南
架构
小马爱打代码9 小时前
DDD:领域驱动设计 - 驾驭复杂业务系统的架构艺术
架构
e***877010 小时前
windows配置永久路由
android·前端·后端
fouryears_2341712 小时前
现代 Android 后台应用读取剪贴板最佳实践
android·前端·flutter·dart
YF021113 小时前
Frida for MacBook/Android 安装配置
android·前端