代码之家  ›  专栏  ›  技术社区  ›  JHH

Android Studio项目运行良好,但build APK由于“多个dex文件…”而失败

  •  0
  • JHH  · 技术社区  · 8 年前

    使用Android Studio 3.0,我有一个Android应用程序项目,其布局如下:

    app
     |
     - lib-foo
     - lib-bar
    

    所以我有一个应用程序模块,使用两个库模块 lib-foo 和 lib-bar 分别地

    现在,有趣的部分来了:

    • 这个 lib foo公司 模块直接包含Java源文件 com.foo.Foobar.java .
    • 这个 lib栏 模块包含一个内联的。aar文件,来源为 implementation files('libs/some-3rd-party-lib.aar') ,然后是这个库 而且 包含 通用域名格式。富。福巴。Java语言 .

    运行和调试这个项目工作得很好,一个APK被生产出来并在电话上运行得很好。然而,当我尝试“构建APK”时,它失败了

    Multiple dex files define Lcom/foo/Foobar;
    

    是的,该文件确实存在于两个地方,但我不完全确定该怎么看。我可以想象,“run”和“Build APK”之间的一个区别是使用proguard等,但这是“Build APK”在直接从AS works运行应用程序时失败的原因,还是区别在哪里?

    是否不允许在两个不同的库模块中的两个位置具有相同的源文件,其中该文件仅在模块内部使用?我知道最终,整个类集合被合并为一个 classes.jar 在最终的APK中,但肯定必须对完全相同的类的副本有某种容忍度,否则每个人都会对大量库中大量使用的apache commons等内容产生冲突?

    或者在两个不同的模块内部允许重复文件,但它是静态的直接包含。把事情搞砸的aar文件?

    我如何解决这个问题?如果我可以控制第三方库,我想我可以将公共文件提取为另一个包含最小公分母的库,并从需要它们的两个模块中将其作为渐变依赖项进行源,但我无法控制第三方库。也许将第三方库放在Maven上,并将其作为版本化依赖项而不是静态文件来源代码,就可以做到这一点,如果这只是由内联引起的一些bug的话。aar包含(大量推测)?

    我想确切地了解为什么会失败,为什么直接从AS运行应用程序时不会失败,以及如何解决它。我不想重命名 通用域名格式。富。福巴。Java语言 到 com.foo.MyRenamedFooBar.java 消除冲突。

    1 回复  |  直到 8 年前
        1
  •  3
  •   CommonsWare    8 年前

    DEX文件中有基于其完全限定Java类名的类。因此,当谈到Java类时 old movie and TV show ,对于任何给定的完全限定Java类名,“只能有一个”。

    对于来自工件库的依赖项(您的apache commons场景),Gradle可以将其清除,并且只包含一次依赖项。然而,这在工件的级别上起作用。例如,如果您的应用程序依赖于apache commons 和 如果源代码中有一个来自apache commons的Java类,那么该类将有两个副本(一个来自依赖项,一个来自源代码),Gradle对此无能为力。

    通常,如果有2个以上的类具有相同的完全限定类名,则会出现某种生成错误。Android Studio 3.0大大提高了对该场景的检测 太多了 堆栈溢出时报告的来自重复类的新生成错误数。

    很明显,您遇到了一个边缘案例,Android Studio没有检测到它,至少在所有场景中都是如此(例如,Instant Run丢失了它)。如果您可以创建一个可复制的测试用例,请将问题归档,工具团队可能能够解决它。