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

相关推荐
失散131 小时前
分布式专题——10.1 ShardingSphere介绍
java·分布式·架构·shardingsphere·分库分表
天天爱吃肉82182 小时前
【比亚迪璇玑架构深度解析:重新定义智能电动汽车的“整车智能”】
数据库·人工智能·嵌入式硬件·架构·汽车
00后程序员张2 小时前
iOS App 混淆与资源保护:iOS配置文件加密、ipa文件安全、代码与多媒体资源防护全流程指南
android·安全·ios·小程序·uni-app·cocoa·iphone
二进制coder2 小时前
深入解析 AST2600 H2B 接口:架构、原理与完整开发指南
linux·架构
jmoych2 小时前
架构思维:在复杂系统中寻找秩序的底层逻辑
架构·模型·架构思维·系统化
huluang3 小时前
“能量逆流泵”:一种基于电容阵与开关矩阵的超高效大功率降压架构
架构
阿雄不会写代码3 小时前
分布式部署的A2A strands agents sdk架构中的最佳选择,使用open search共享模型记忆
分布式·架构
柳岸风4 小时前
Android Studio Meerkat | 2024.3.1 Gradle Tasks不展示
android·ide·android studio
编程乐学4 小时前
安卓原创--基于 Android 开发的菜单管理系统
android
一个帅气昵称啊4 小时前
Docker命令大全:从基础到高级实战指南
docker·容器·eureka·架构·.net