如何在没有重复类冲突的情况下混淆两个不同`.aar` 的包名?

问题描述

假设我有 3 个子项目(模块):

:libraryA
:libraryB
:app

:app 取决于 :libraryA:libraryB。在我的图书馆中,我有

// libraryA
com.example.libraryA.Class1
// libraryB
com.example.libraryB.Class2

当我在这两个库上运行 R8(如 proguard)时,它们生成以下类:

// libraryA - Class1
a.a.a.a
// libraryB - Class2
a.a.a.a

(note that 2 different classes end up having the same signature)

当我构建使用 :app.aar 的混淆 :libraryA:libraryB 变体时,我遇到以下构建失败:

Caused by: com.android.tools.r8.utils.b: Type a.a.a.a is defined multiple times:

一种解决方案是在我的库的 proguard 规则中使用 -keeppackagenames

-keeppackagenames com.example.**

但我想实际上混淆包名称。我在这里有哪些选择?

是否可以在唯一但确定的基础上混淆包名称?例如,我希望发生以下情况:

  • com.example.libraryA -> a.a.a
  • com.example.libraryB -> a.a.b

这将避免任何潜在的冲突。这样的事情可以实现吗?

解决方法

当您使用 R8 打包库以进行分发时,您必须使用 -keeppackagenames,否则库的使用者可能会获得重复的类。

有选项 -flattenpackagehierarchy-repackageclasses 来控制非保留类的去向。对于 R8 库本身 we use both

但是,当您构建使用库的最终应用程序时,包括库在内的所有应用程序都将作为一个整体进行混淆,因此在用作依赖项时不必对库进行混淆。