Конфигурации сборки на основе варианта приложения (BuildType + Flavor)

Я пытаюсь установить signingConfig, manifestPlaceholders, buildConfigField для варианта приложения. Я могу установить их для каждого buildType или! productFlavor независимо, но мне нужно установить их на основе обоих productFlavor и! buildType.

buildTypes{
  getByName("debug"){}
  getByName("release"){}
  create("staging"){}
}

productFlavors {
  create("global"){}
  create("local"){}
}

В приведенном выше примере есть 3 разных типа сборки и 2 разных вкуса продукта. Это означает, что всего 6 вариантов APK. Например, для каждого из этих APK (globalRelease, globalStaging, globalDebug, localRelease, localStaging, localDebug) я хочу использовать разные signingConfig. Как мне установить это?

Пытался:

  • Если я установлю его в buildType, то будет только 3 разных signingConfigs
  • Если я установлю его во вкусе, то будет только 2 разных файла signingConfig.
  • Если я попытаюсь установить его в applicationVariants.all{}, нет функций установки, только геттеры для объекта Variant (ссылка)
  • установка полей в (variant.mergedFlavor as DefaultProductFlavor) не добавляет значения buildConfigField в BuildConfig.java (ссылка)

person Jemshit Iskenderov    schedule 01.04.2020    source источник
comment
Аналогично без ответа: stackoverflow.com/questions/ 32742184/   -  person Jemshit Iskenderov    schedule 02.04.2020


Ответы (1)


Чтобы внести изменения в разные варианты (buildType+productFlavor), мне пришлось использовать android.applicationVariants.all{}. Но разные пути, используемые для достижения нескольких signingConfig, manifestPlaceholders, buildConfigField

1) манифест-заполнители

applicationVariants.all{
    val variant = this
}

Нет геттера/сеттера для manifestPlaceholders на объекте variant. Следуя этому, мы можем сделать variant.mergedFlavor изменяемым. Установка manifestPlaceholders на variant.mergedFlavor сработала.

import com.android.builder.core.DefaultProductFlavor

applicationVariants.all{
    val manifestPlaceholders: Map<String, String>
    val variant = this
    val mutableMergedFlavor = variant.mergedFlavor as DefaultProductFlavor
    mutableMergedFlavor.addManifestPlaceholders(manifestPlaceholders)
}

2) buildConfigField

Используя тот же подход, вызов addBuildConfigField(ClassFieldImpl(type, name, value)) на mutableMergedFlavor не сработал. Но вместо этого его можно установить непосредственно на variant.

import com.android.builder.internal.ClassFieldImpl

applicationVariants.all{
    val buildConfigFields: List<ClassFieldImpl>
    val variant = this
    buildConfigFields.forEach { 
        variant.buildConfigField(it.type, it.name, it.value) 
    }
}

3) signingConfig signingConfig можно установить для mutableMergedFlavor, показанного выше, за исключением вариантов debug. Все варианты debug используют параметры подписи по умолчанию, даже если вы установили их на variant.mergedFlavor. Но если вы установите default значение null, то вы также может переопределить его.

import com.android.builder.core.DefaultProductFlavor

signingConfigs {
    create("myDebug") {}
}
buildTypes {
    getByName("debug") {
        signingConfig = null // to override
    }
}
applicationVariants.all{
    val variant = this
    val mutableMergedFlavor = variant.mergedFlavor as DefaultProductFlavor
    mutableMergedFlavor.signingConfig = signingConfigs.getByName("myDebug")
}

Чтобы собрать все вместе:

import com.android.build.gradle.api.ApplicationVariant
import com.android.builder.internal.ClassFieldImpl
import com.android.builder.model.SigningConfig
import com.android.builder.core.DefaultProductFlavor
import java.util.*

fun configureVariant(variant: ApplicationVariant,
                     signingConfig: SigningConfig,
                     buildConfigFields: List<ClassFieldImpl>,
                     manifestPlaceholders: Map<String, String>) {

    println("configureVariant: ${variant.name}")
    buildConfigFields.forEach {
        variant.buildConfigField(it.type, it.name, it.value)
    }

    val mutableMergedFlavor = variant.mergedFlavor as DefaultProductFlavor
    mutableMergedFlavor.signingConfig = signingConfig
    mutableMergedFlavor.addManifestPlaceholders(manifestPlaceholders)
}

android {
    signingConfigs {
        create("myDebug") {}
        create("myRelease") {}
    }

    flavorDimensions("region")
    productFlavors {
        create("global") {
            setDimension("region")
            setApplicationId("")
        }
        create("local") {
            setDimension("region")
            setApplicationId("")
        }
    }

    buildTypes {
        getByName("debug") {
            signingConfig = null
        }
    }

    applicationVariants.all {
        val variant = this
        when {
            variant.name.equals("localDebug", true) -> {
                configureVariant(
                        variant,
                        signingConfigs.getByName("localDebug"),
                        listOf(ClassFieldImpl("String", "NAME", "\"VALUE\"")),
                        mapOf("KEY" to "VALUE")
                )
            }
            variant.name.equals("globalStaging", true) -> {
                configureVariant(
                        variant,
                        signingConfigs.getByName("globalStaging"),
                        listOf(ClassFieldImpl("String", "NAME", "\"VALUE2\"")),
                        mapOf("KEY" to "VALUE2")
                )
            }
        }
    }
}

person Jemshit Iskenderov    schedule 02.04.2020
comment
После Android Studio 4.0.0 (gradle 6.1.1) DefaultProductFlavor не может быть разрешен. AbstractProductFlavor можно использовать как обходной путь - person Jemshit Iskenderov; 25.08.2020