Android DEX 65k 异常 - Gradle 模块 - 还有其他想法吗?

Android DEX 65k Exception - Gradle Module - Any other Idea?

更新重复问题:
我不想使用 multidex。应该有一个没有它的解决方案,因为“:app”使用的 classes 不需要这个巨大的库包。

我目前正在从事一个网络项目:应用程序服务器和 android 客户端应用程序。我已经完成了服务器的 pre-alpha 版本,现在我想开始编写 android 客户端应用程序。

我的想法:我想将服务器 git 存储库作为 git 子模块包含在我的 android 项目文件夹中,以便 gradle 可以将其用作我的 ':app' 项目。
但是:服务器回购使用 jersey restful classes。因此,如果我将服务器 gradle 项目作为依赖项包含在内,android 构建将失败并出现常见的 "Unable to execute dex: method ID not in [0, 0xffff]: 65536" 错误:DEX 65k 问题。

嗯,我的 android 客户端项目不使用任何需要 jersey 依赖项的 class。只有少数 classes 包括对服务器提供的数据的解析和处理方法。我已将它们包含在服务器存储库中,因此您始终拥有适合实际服务器结构的正确客户端 classes。如果我为客户端 classes 创建第二个存储库,它们可能不会每次都同步。

我该如何解决这个问题?我考虑过将服务器回购分成两个 gradle 模块但相同的 git 回购。

有什么想法吗??

PS:65k 问题:我总是在 android 客户端项目中包含 classes,它们只有 java-自己的依赖项。 65k 是指 "available" 还是 "used" 方法?

使用两个 Gradle 模块听起来是最好的解决方案,如果您使用的是服务器提供的一些 classes 而不是大部分服务器代码。 Java 在组装 class 路径时非常自由,使所有可能使用的 classes 可用;然而,这意味着如果您不注意 class 路径,dexer 将假定所有这些 classes 和方法都应该在您的 dex 中可用,并转换更多比你实际需要的要多。

您也可以考虑启用 Proguard,它可以 trim 减少未使用的 class 方法和内联短方法。这两者都使 class 倒计时,尽管有一些额外的处理成本和一些额外的配置。如果您使用反射或本机代码,您将特别需要小心,因为 Proguard 可能不够智能,无法检测未通过正常 Java 调用语义调用的方法。


关于限制的进一步解释(总共 65,536 个方法和字段 references)我在评论中绝对赞同 Anubian Noob 的 link (How to shrink code - 65k method limit in dex)。除非绝对必要,否则你不应该切换到 Multidex:所有代码仍然需要下载到设备上(并在 Lollipop 设备和更高版本上转换为 OAT 格式),如果代码绝对不必要,这将浪费时间和数据。相反,将尽可能小的输入 jar 提供给 dexer,这意味着拆分您的模块或使用 Proguard。