☰
SDK依赖冲突?一招搞定打包闪退难题
2026/10/16 2:12:11 网站建设 项目流程

一句话

两个 SDK 各自带了同一个"零件",但版本不一样,游戏不知道该用哪个,于是编译失败或者运行时闪退。


一、什么是"依赖"?

SDK 不是从零写出来的,它内部也会用别人做好的工具包。比如:

  • 联网用OkHttp
  • 处理数据用Gson
  • 谷歌相关功能用Google Play Services

这些被 SDK 用到的工具包,就叫依赖。

打个比方:你买了两台家电(SDK A 和 SDK B),每台都附带了一根电源线(依赖)。


二、冲突是怎么发生的?

你的游戏 ├── 广告 SDK → 自带 Gson 2.8 └── 统计 SDK → 自带 Gson 2.10

游戏里同时出现两个 Gson,就会出现两种情况:

情况比喻表现
两份一模一样的东西两根完全一样的电源线,插座只能插一根打包失败,报Duplicate class
只留了一份,但版本不对留下的是旧电源线,新家电插不上打包成功,但玩的时候闪退,报NoSuchMethodError或ClassNotFoundException

第二种更麻烦,因为测试时不一定能发现,上线后才崩。


三、怎么看懂报错

遇到冲突时,报错信息里会直接写出是哪个零件。比如:

Duplicate class com.google.gson.Gson found in modules gson-2.8.6.jar gson-2.10.1.jar

翻译成大白话:Gson 有两份,一份 2.8.6,一份 2.10.1。

常见报错速查:

报错关键词意思
Duplicate class同一个零件有两份(Android)
NoSuchMethodError/ClassNotFoundException零件版本不对,找不到需要的功能(Android)
duplicate symbol同一个零件有两份(iOS)
Program type already present和Duplicate class一样,老版本工具的说法

四、解决办法(从简单到复杂)

以下以Unity 打包安卓为例。

办法 1:删掉多余的那份文件

很多 SDK 是把.aar或.jar文件直接放进Assets/Plugins/Android/文件夹的。

打开这个文件夹看看,如果发现:

Assets/Plugins/Android/ ├── gson-2.8.6.jar ← 旧的 └── gson-2.10.1.jar ← 新的

删掉旧的,留下新的,重新打包。

一般留新版本,因为新版本通常兼容旧版本的用法。删完一定要在手机上把相关功能都试一遍。


办法 2:用 EDM4U 统一管理(推荐)

手动删文件容易出错。Unity 上有个专门管依赖的免费工具:External Dependency Manager(简称 EDM4U)。大部分正规 SDK(Firebase、各大广告平台)都自带它。

它的作用就像一个管家:每个 SDK 告诉管家"我需要什么",管家统一去下载,同一个零件只下载一份,并自动选一个合适的版本。

每个 SDK 的需求写在一个 xml 文件里,放在任意Editor文件夹下,例如Assets/MySDK/Editor/MySDKDependencies.xml:

<dependencies><androidPackages><!-- 告诉管家:我需要 Gson 2.10.1 --><androidPackagespec="com.google.code.gson:gson:2.10.1"/></androidPackages></dependencies>

然后在菜单里点:

Assets → External Dependency Manager → Android Resolver → Force Resolve

管家会把所有 SDK 的需求汇总,自动处理重复的版本。

⚠️ 用了 EDM4U 之后,不要再手动往Plugins/Android里拷同样的 jar/aar,否则又会重复。


办法 3:修改 Gradle 配置,强制指定版本

如果管家也搞不定,可以直接告诉打包工具"只用哪个版本"。

第一步:打开自定义配置文件

Edit → Project Settings → Player → 安卓图标 → Publishing Settings → 勾选 Custom Main Gradle Template

项目里会出现Assets/Plugins/Android/mainTemplate.gradle。

第二步:在文件里加上下面这段

// 不管哪个 SDK 要什么版本,Gson 一律用 2.10.1configurations.all{resolutionStrategy{force'com.google.code.gson:gson:2.10.1'}}

另一种写法:不让某个 SDK 带它自己的那份

dependencies{implementation('com.example:ad-sdk:1.0.0'){// 广告 SDK 别带 Gson 了,用别人的就行exclude group:'com.google.code.gson',module:'gson'}**DEPS**}

**DEPS**是 Unity 自带的占位符,不要删掉它。


办法 4:找 SDK 厂商

有些 SDK 把别人的零件直接打包进了自己的文件里,你删不掉、也排除不了。

这时只能联系厂商,问他们:

  • 有没有新版本解决了这个问题?
  • 能不能提供一个不内置这个零件的版本?

五、苹果手机(iOS)怎么办?

iOS 上的报错一般是:

duplicate symbol _xxxxx in: libSDK_A.a libSDK_B.a

意思是两个 SDK 都内置了同一段代码。

解决思路和安卓一样:

  1. 优先使用 CocoaPods 版本的 SDK(EDM4U 会自动帮你管理),它会像管家一样只装一份;
  2. 尽量不要把.a/.framework文件手动拖进项目;
  3. 实在不行,找厂商要新版本。

在 xml 里写 iOS 需求的方式:

<dependencies><iosPods><iosPodname="GoogleUtilities"version="~> 7.0"/></iosPods></dependencies>

六、怎么避免以后再遇到

习惯说明
一次只接一个 SDK接完立刻打包测试,出了问题马上知道是谁引起的
优先选支持 EDM4U 的 SDK让管家管,比手动拷文件靠谱
不随手拷 jar/aar文件越乱,越容易重复
升级 SDK 后完整测一遍版本冲突经常在升级后才出现
记下每个 SDK 的版本出问题时方便回退

七、总结

  • 是什么:两个 SDK 带了同一个零件的不同版本。
  • 表现:打包失败(有两份),或者玩的时候闪退(版本不对)。
  • 怎么查:看报错,里面会写出零件名字和版本。
  • 怎么修:
    1. 删掉多余的旧文件;
    2. 用 EDM4U 统一管理;
    3. 在 Gradle 里强制指定版本或排除;
    4. 找厂商要新版本。

记住一句话:同一个零件,游戏里只能留一份,并且要选大家都能用的那个版本。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询