2

在我的日常工作中,我开发 Android 库(我们称之为)libA 和 libB。在某些时候,我们已经意识到它们之间有很多共享代码,因此我们将这些代码移动到另一个文件夹并使用sourceset指令引用它。

当我们构建一个项目时,我们开始收到“错误:程序类型已经存在”,这让我认为 Android 编译器变得更智能,或者项目结构的更改(我们已经合并了项目)使重复可见。无论如何,这个问题仍然是断断续续的,但它可能总是一个坏主意。谷歌对这个主题有这样的看法。

我正在考虑的解决方案是将共享代码移至单独的模块。这样,每个类只编译一次。我做了一个简单的项目来测试这个架构。

生成的项目将具有以下模块:

  • 演示应用程序(lib* 或所有共享应用程序)
  • 库A
  • 库B
  • 共享库

这提出了以下问题:

  • 这是正确的方法吗?我意识到这可能是基于意见的,但这是一个边缘案例,我无法在有关命名空间冲突的更一般问题的海洋中找到任何讨论。
  • 我们如何分发共享代码?理想情况下,我想以某种方式将它捆绑到 lib* 的 aar 中。(目前,lib* aar 不包括共享代码。)否则,我只会分发两个 aar 文件。
  • java/android 编译器如何处理这个问题?假设我尝试用相同的包/类编译两个库,我假设它会发出上述错误,或者只是选择一个并尝试编译。
  • 流行的图书馆如何处理这个问题?我可以很容易地看到 okHTTP 捆绑到几个 3rd 方库和主应用程序中。我特别询问 API 破坏版本差异和非 API 破坏版本。
  • 只是为了完整起见,我知道 DEX 没有多个具有相同名称的类的选项。我假设这一切都在java编译期间被整理出来。IIRC,我做了检查,DEX 创建有一个检查这个的 linter/validator。清除此问题并引用相关链接的额外积分。

笔记:

  • 这对于 C/C++ 等来说不是问题,因为您可以选择使用静态库并复制代码。
  • 一些关于命名空间冲突的 S/O 问题实际上是关于变量阴影的(例如java 命名空间冲突)。
  • 这个答案向我证明了我对这个问题的直觉是正确的。不同的 jar 可能会导致此问题,但编译会检测到它。
  • 这个问题,尤其是 CommonsWare 的回答暗示了一个更大的讨论。
4

0 回答 0