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+
相关推荐
robotx12 小时前
安卓线程相关
android
消失的旧时光-194313 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon13 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon14 小时前
VSYNC 信号完整流程2
android
dalancon14 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户693717500138415 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android15 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才16 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶16 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle
汪海游龙17 小时前
开源项目 Trending AI 招募 Google Play 内测人员(12 名)
android·github