如何以一种灵活的方式使用 Android Flavors 覆盖 Java/Kotlin 类?

How to have a flexible way to override Java/Kotlin classes with Android Flavors?

提问人:Charly Lafon 提问时间:6/26/2019 最后编辑:Charly Lafon 更新时间:2/12/2021 访问量:448

问:

我正在开发一个使用 .我的项目目前有 4 种口味,但很快就会有 6-7 种口味。 假设我有 4 种口味,f1、f2、f3 和 f4。Flavors

我非常熟悉 main/ 中被 flavor 中的资源覆盖的 Android 资源,但类不是(cf “duplicate classes” 编译错误)。因此,如果我在 main/ 中并且只想在 f3 中更改这个类,我知道有几种解决方案:MyClass

  • 从 main/ 中删除 MyClass 并将其放入所有风格中,然后在 f3/MyClass 中进行修改。这将导致维护地狱,我不想那样做。
  • 在 main/ a 中具有与 MyClass 相同的内容,在 f1、f2、f4 中使用空的 MyClass 继承它,并在 f3 中继承它并进行修改。同样,我不喜欢这个解决方案,因为它使类号增长得非常快,这破坏了项目的可读性。实际上,我目前使用的项目使用了这个解决方案,这是一个噩梦,因为这个项目很大。AbstractMyClass

我通过这篇漂亮的帖子找到了另一个解决方案:https://stackoverflow.com/a/30548238/8096984

这篇文章描述了 f1、f2 和 f4 将有一个指向包含 MyClass 的公共附加 sourceSet 的链接(因此 MyClass 将不再位于 main/ 中),而 f3 将没有它。因此,它可以自由地定义自己的 MyClass 实现,而不会出现重复类错误。

此解决方案似乎是 3 个解决方案中最好的,但对于 1 个覆盖。 如果现在我有一个 MyClass2,我只想在 f2 中有所不同怎么办?如果我将 MyClass2 放在额外的 sourceSet 中,那么我将不得不将 f3 链接到 sourceSet,从而破坏我由于重复类错误而进行的第一个覆盖。

我必须创建另一个 sourceSet 吗?如果我这样做了,那么我真的不喜欢这个解决方案,因为你可以想象在一个使用 6-7 种风格的大项目中我必须创建的 sourceSet 数量......

我该怎么办?

安卓 android-gradle-plugin android-productflavors android-build-flavors

评论


答:

0赞 matdev 2/12/2021 #1

下面是一个仅需要三个 sourceSet 的解决方案:

将 F1、F2、F3 和 F4 通用的代码文件移动到一个文件夹中,例如:

src/common/java

然后将 f1、f2 和 f4 风格代码复制到通用的 src 目录中:

src/generic/java

从中删除这些文件。src/common/java

然后,将特定 f4 风格文件的副本创建到特定的 src 目录中,例如

src/specific/java

然后,应按如下方式更新脚本:build.gradle

android {
    ...
    productFlavors {
        f1 {
            ...
        }
        f2 {
            ...
        }
        f3 {
            ...
        }
        f4 {
            ...
        }
    }
    sourceSets {
        f1.java.srcDirs('src/generic/java', 'src/common/java')
        f2.java.srcDirs('src/generic/java', 'src/common/java')
        f4.java.srcDirs('src/generic/java', 'src/common/java')

        f3.java.srcDirs('src/specific/java', 'src/common/java')
    }
}

此解决方案还可用于覆盖活动类。