Создавайте ароматы для разных версий того же класса

У меня есть проект, структурированный следующим образом:

project/
   |
   |---src/
        |---flavorA2/
        |      |
        |      |---java/
        |      |     |---com.abc.flavorA.mk2
        |      |                 |-----classA.java
        |      |                 |-----classB.java
        |      |---res/
        |      |---AndroidManifest.xml
        |
        |---main
        |      |---java/
        |      |     |---com.abc.flavorA
        |      |                 |-----classA.java
        |      |                 |-----classB.java
        |      |                 |-----classC.java
        |      |                 |-----classD.java
        |      |---res/
        |      |    |---drawable/
        |      |    |---layout/
        |      |    |---values/
        |      |         
        |      |---AndroidManifest.xml
        |
        |---flavorA

flavorA будет полностью использовать источник и активы из main, а flavorA2 имеет небольшие изменения в classA и classB, а имя пакета также будет изменено на com.abc.flavorA.mk2.

У меня был файл build.gradle следующим образом:

...
buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
    productFlavors {
        flavorA2 {
            packageName "com.abc.flavorA.mk2"
            versionCode 2
            versionName "1.0.1"
        }

        flavorA {
            packageName "com.abc.flavorA"
        }
    }
...

Я запускаю код, выбирая вариант сборки flavorA2. Однако результаты работы показывают, что gradle по-прежнему выбирают классы (classA и classB) из main вместо использования измененной версии внутри flavorA2.

Я что-то пропустил?

Ответ 1

Поскольку у вас есть классы под 2 различными пакетами, это совершенно разные классы. Таким образом, классы не заменяют друг друга.

С ароматами вы не можете переопределять файлы классов. Итак, один способ выполнить то, что вы хотите, - это переместить эти классы из main и в flavorA.

Итак, у вас будет что-то вроде этого:

project/
   |
   |---src/
        |---flavorA2/
        |      |
        |      |---java/
        |      |     |---com.abc
        |      |                 |-----classA.java
        |      |                 |-----classB.java
        |      |---res/
        |      |---AndroidManifest.xml
        |
        |---main/
        |      |---java/
        |      |     |---com.abc.flavorA
        |      |                 |-----classC.java
        |      |                 |-----classD.java
        |      |---res/
        |      |    |---drawable/
        |      |    |---layout/
        |      |    |---values/
        |      |         
        |      |---AndroidManifest.xml
        |
        |---flavorA/
        |      |---java/
        |      |     |---com.abc
        |      |                 |-----classA.java
        |      |                 |-----classB.java

Таким образом, всякий раз, когда вы выбираете аромат, будет видна только одна версия ClassA и ClassB.

Ответ 2

В основном варианте сборки класс A com.abc.flavorA.classA, а в flavorA2 - com.abc.flavorA.mk2.classA. Это два разных полнофункциональных имени класса и, следовательно, два разных класса.

Вы не можете переопределить целые классы в аромате. В зависимости от того, что вы хотите сделать, вам может понадобиться изучить механизм BuildConfig - короче говоря, это класс, который генерируется системой сборки, которая может иметь значения или утверждения, которые зависят от типа сборки и вкуса. Вы можете иметь код времени выполнения, который смотрит на константы в этом классе и изменяет его поведение.

См. Android Studio Update 0.4.0 не смог найти buildConfig() для получения дополнительной информации о синтаксисе, но вкратце, он выглядит следующим образом:

productFlavors {
    flavor {
      buildConfigField "boolean", "MY_FLAG", "true"
    }
}

Ответ 3

Вам нужно указать sourceSets в файле сборки. Вам нужно изменить структуру каталогов, чтобы сделать так, чтобы только имена папок были разными, все под каталогом java должно быть одинаковым, поэтому удалите mk2 из имени класса. Я не уверен, что синтаксис полностью правильный, но он должен выглядеть следующим образом:

android {
    sourceSets {
        flavorA {
            java {
                srcDirs = ['src/flavorA/java']
            }
        }

        flavorA2 {
            java {
                srcDirs = ['src/flavorA2/java']
            }
        }
    }
}