Как иметь гибкий способ переопределить классы Java/Kotlin с помощью Android Flavors?

Я работаю над проектом Android, который использует Flavors. Сейчас в моем проекте 4 вкуса, но скоро будет 6-7 вкусов. Допустим, у меня есть 4 вкуса: f1, f2, f3 и f4.

Я очень хорошо знаком с ресурсами Android в main/, которые переопределяются теми, что в ароматах, но классы - нет (см. Ошибка компиляции «дубликаты классов»). Итак, если у меня есть MyClass в main/ и я хочу изменить этот класс только в f3, я понимаю, что есть несколько решений:

  • Удалите MyClass из main/ и поместите его во все варианты, затем выполните модификации в f3/MyClass. Это приведет к аду обслуживания, я не хочу этого делать.
  • Имейте в main/ AbstractMyClass, который имеет то же содержимое, что и MyClass, наследуйте его с пустым MyClass в f1, f2, f4 и наследуйте его в f3 и выполняйте модификации. Опять же, мне не нравится это решение, потому что оно заставляет номер класса расти очень быстро, и это разрушает читабельность проекта. На самом деле проект, с которым я сейчас работаю, использует это решение, и это кошмар, так как проект большой.

Я нашел другое решение в этом прекрасном посте: https://stackoverflow.com/a/30548238/8096984.

В этом посте описывается, что f1, f2 и f4 будут иметь ссылку на общий дополнительный набор источников, содержащий MyClass (поэтому MyClass больше не будет в main/), а у f3 его не будет. Таким образом, можно было бы свободно определять собственную реализацию MyClass без ошибки дублирования класса.

Это решение кажется лучшим из 3, но для 1 приоритетнее. Что, если теперь у меня есть MyClass2, который я хочу отличать только в f2? Если бы я поместил MyClass2 в дополнительный набор источников, то мне пришлось бы связать f3 с набором источников и, следовательно, нарушить первое переопределение, которое я сделал из-за ошибки дублирования класса.

Должен ли я создавать еще один исходный набор? Если я это сделаю, то мне это решение не очень нравится, потому что вы можете себе представить количество наборов исходников, которые мне пришлось бы создать в большом проекте, использующем 6-7 вариантов...

Что я должен делать?


person Charly Lafon    schedule 26.06.2019    source источник


Ответы (1)


Вот решение, для которого требуется только три исходных набора:

Переместите файлы кода, общие для ваших вариантов 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')
    }
}

Это решение также работает для переопределения классов активности.

person matdev    schedule 12.02.2021