Android多SDK合并为单个JAR包的完整指南

痛点

  • 多 SDK 分散:每个功能模块单独提供 JAR,用户需要逐一集成和管理
  • 调用复杂:不同模块间存在依赖和包名冲突,用户在项目中使用不方便
  • 升级维护困难:每次更新都要同步多个 JAR,容易出错

一、核心原理

1.1 最推荐的方案:源码合并 + 下层库作为"源码目录"加入

多 SDK 合并时,最终有效的构建环境只有顶层 SDK,因此最稳定的方式是:

diff 复制代码
源码合并(sourceSets)  
+ 移除模块依赖  
+ 将下层 SDK 作为源码目录引入(而不是 module)

Android Studio 会把下层 SDK 当成普通源码,自然不会爆红,也不会再触发 module 依赖的复杂机制。


1.2 为什么不能继续使用 module 依赖?

java 复制代码
dependencies {
    api project(':sdk-core-lib')  // ❌ 不推荐
}

问题:

  • AAR/JAR 输出不一定包含所有依赖模块代码
  • 需要额外处理传递依赖
  • fat-aar 插件在 Gradle 8+ 兼容性差
  • 模块之间 BuildConfig、Manifest、资源合并容易冲突
  • 最重要:module 依赖让下层 SDK 的 build.gradle 继续生效(会导致混淆等配置难以统一管理)

1.3 最关键的优化:用 sourceSets 把下层 SDK 当成"源码目录"

比直接复制代码更干净 ------ 下层 SDK 不再是 module,只是一个源码目录。

css 复制代码
android {
    sourceSets {
        main {
            java.srcDirs += ['../SDK_Core/src/main/java']
            java.srcDirs += ['../SDK_Base/src/main/java']
            res.srcDirs  += ['../SDK_Core/src/main/res']
            res.srcDirs  += ['../SDK_Base/src/main/res']
        }
    }
}

同时从 settings.gradle 中删除:

php 复制代码
include ':SDK_Core'
include ':SDK_Base'

优点:

  • Android Studio 能识别源码,不再爆红(你遇到的问题的核心原因)
  • 不再有 Gradle module 带来的依赖逻辑
  • 完全由顶层 SDK 的 build.gradle 决定最终产物
  • 源码共享更干净,不需要复制

缺点:

  • 不再能享受 Gradle dependency graph(因为不是 module)
  • 无法单独编译下层 SDK(但通用 SDK 开发通常不需要)

二、适用架构与合并策略

以典型结构为例:

复制代码
SDK_Standard(对客户的最终输出)
 ├── SDK_Core
 │     └── SDK_Base

所有差异化功能由顶层 SDK(Standard / Custom_A / Custom_B)决定。


三、核心规则(⭐ 极重要)

规则 1:所有下层 SDK 必须作为源码目录存在

❌ 不要是 module

❌ 不要使用依赖

✔ 使用 sourceSets 直接引用源码目录(不会爆红)


规则 2:只有顶层 SDK 的 build.gradle 生效

下层的 build.gradle 完全无效(因为不再是 module)。

失效内容:

全部迁移到顶层。


规则 3:资源文件自动合并,但必须避免冲突

建议命名规范:

SDK 前缀
SDK_Base base_
SDK_Core core_
SDK_Standard standard_

规则 4:避免包名冲突

下层 SDK 必须独立包目录,例如:

csharp 复制代码
com.company.base.**
com.company.core.**
com.company.sdk.standard.**

四、完整实现步骤


4.1 顶层 build.gradle(唯一有效)

arduino 复制代码
android {
    namespace 'com.company.sdk.standard'
    compileSdk 34

    defaultConfig {
        minSdk 21
        targetSdk 34
    }

    sourceSets {
        main {
            // 源码合并
            java.srcDir '../SDK_Core/src/main/java'
            java.srcDir '../SDK_Base/src/main/java'

            // 资源合并(如需要)
            res.srcDir '../SDK_Core/src/main/res'
            res.srcDir '../SDK_Base/src/main/res'
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                         'proguard-rules.pro'
        }
    }
}

4.2 迁移所有依赖到顶层

arduino 复制代码
dependencies {
    // 来自 Core
    implementation 'androidx.core:core-ktx:1.12.0'

    // 来自 Base
    implementation 'com.google.code.gson:gson:2.10.1'
}

4.3 BuildConfig 失效问题(非常常见)

下层 SDK 不再是 module,所以不会生成 BuildConfig。

解决方式 A(推荐)

修改引用路径:

arduino 复制代码
// from
import com.company.sdk.core.BuildConfig;

// to
import com.company.sdk.standard.BuildConfig;

解决方式 B(无需改源码)

手动创建对应 BuildConfig:

css 复制代码
SDK_Standard/src/main/java/com/company/sdk/core/BuildConfig.java

4.4 混淆规则合并(放在顶层)

csharp 复制代码
# Base
-keep class com.company.base.** { *; }

# Core
-keep class com.company.core.** { *; }

# 顶层对外接口
-keep public class com.company.sdk.MTTagBleManager { *; }

4.5 最终目录结构(重要)

bash 复制代码
SDK_Standard/
 ├── build.gradle(唯一有效)
 ├── proguard-rules.pro
 └── src/main/java/
       ├── com/company/sdk/standard/...
       ├── com/company/core/...     ← via sourceSets
       └── com/company/base/...     ← via sourceSets

五、为什么之前代码会爆红?

因为:

  • 你删掉 settings.gradle 里的 include
  • 但没有把 SDK_Core / SDK_Base 作为 sourceSets 手动加入
  • Android Studio 不知道这些目录是源码目录
  • 所以爆红(找不到类)

只要加上这个:

核心痛点

  • 多 SDK 分散:每个功能模块单独提供 JAR,用户需要逐一集成和管理
  • 调用复杂:不同模块间存在依赖和包名冲突,用户在项目中使用不方便
  • 升级维护困难:每次更新都要同步多个 JAR,容易出错
css 复制代码
android {
    sourceSets {
        main {
            java.srcDirs += ['../SDK_Core/src/main/java']
        }
    }
}

即时恢复正常。

这是你目前问题的根源,并且已经彻底解决。


六、总结

能力 为什么必须使用源码目录方式
不爆红 Android Studio 能识别源码
打包稳定 所有代码由顶层统一构建
混淆统一 避免多 module 冲突
完全控制 不再受 module 的 build.gradle 干扰
干净 不需要复制源码

最终输出:

  • 单 AAR / 单 JAR
  • 完整包含 Base + Core + Standard 的全部代码
  • 无依赖问题
  • 完整兼容 Gradle 8+
相关推荐
whatever who cares1 小时前
Java/Android中BigDecimal的相关操作
android·java·开发语言
早上好啊! 树哥4 小时前
安卓开发:清除缓存并重启,删除指定路径下的文件缓存
android·缓存
h***34634 小时前
Nginx 缓存清理
android·前端·后端
Tom4i5 小时前
Perfetto 快速上手
android·性能优化·perfetto
fatiaozhang95276 小时前
创维桌面云终端-创维LB2002-黑盒-国科gk6323-2+8G-短接强刷固件包
android·电视盒子·刷机固件·机顶盒刷机·创维lb2002·创维lb2002-黑盒·创维lb2002-白盒
q***718512 小时前
MySQL--》如何在MySQL中打造高效优化索引
android·mysql·adb
IT痴者13 小时前
《PerfettoSQL 的通用查询模板》---Android-trace
android·开发语言·python
游戏开发爱好者813 小时前
iOS IPA 上传工具全面解析,从 Transporter 到开心上架(Appuploader)命令行的高效上架实践
android·ios·小程序·https·uni-app·iphone·webview
alexhilton16 小时前
Jetpack Compose中的阴影艺术
android·kotlin·android jetpack