Андроид Грейдл. Как комбинировать Flavors с buildTypes

Я работаю над приложением белого бренда.

Мы создаем разные варианты для каждого клиента, и у каждого клиента есть Debug и Production API, поэтому я пытаюсь настроить их в Gradle.

Как мне это сделать?

Вот что я пробовал:

buildTypes {
    debug {
        // some configurations
    }
    release {
        // some configurations
    }
}

flavorDimensions "client"
productFlavors {
    company1{
        dimension "client"
        buildConfigField("String", "BASE_URL", "\"https://app.company1/devApi/\"")
    }

    company2 {
        dimension "client"
        buildConfigField("String", "BASE_URL", "\"https://app.company2/devApi/\"")
    }
}

РЕДАКТИРОВАТЬ: я хотел бы иметь возможность определять разные BASE_URL для каждого вкуса и типа сборки.

Flavor company1, отладка BuildType

https://app.company1.com/devApi/

Flavor company1, выпуск BuildType

https://app.company1.com/prodApi/

Flavor company2, отладка BuildType

https://dev.company2.com/api/

Flavor company2, релиз BuildType

https://prod.company2.com/api/

comment
каковы именно ваши требования, которые вы хотите дать во вкусе?   -  person Umair    schedule 15.01.2019
comment
проверьте мой ответ @kike, вы можете изменить его в соответствии с вашими требованиями   -  person Tufan    schedule 15.01.2019
comment
Привет, @kike, ты нашел лучшее решение? У меня такая же проблема сегодня. К сожалению, я не могу получить удовлетворительное решение только с Gradle. Наконец, мне нужно определить две переменные в каждом варианте, одну для отладки, а другую для выпуска. Затем в коде я проверяю buildType, чтобы получить правильное значение. Любое обновление?   -  person Freddie    schedule 26.02.2020
comment
@Freddie Если эти переменные сильно различаются (например, вы не можете комбинировать строки), вам придется установить их в отдельном strings.xml. Проверьте мой ответ ниже и дайте мне знать, если у вас есть дополнительные вопросы.   -  person kike    schedule 26.02.2020


Ответы (5)


Для моей конкретной проблемы, когда URL-адреса сильно отличаются друг от друга, я не смог заставить его работать с Flavors и BuildTypes.

Я смог определить URL-адреса отладки/производства, используя определенные strings.xml для каждого варианта сборки (что представляет собой каждую комбинацию варианта и типа сборки):

Вот структуры папок для этого:

src/flavour1Debug/res/values/strings.xml 
src/flavour1Release/res/values/strings.xml 

а также

src/flavour2Debug/res/values/strings.xml 
src/flavour2Release/res/values/strings.xml 

ДОПОЛНИТЕЛЬНО: это также можно использовать для размещения различных google-services.json файлов.

person kike    schedule 04.03.2019

Попробуйте что-то вроде этого:

buildTypes {
    debug {
        buildConfigField("String", "BASE_URL_PATH", "\"devApi/\"")
    }
    release {
        buildConfigField("String", "BASE_URL_PATH", "\"prodApi/\"")
    }
}

flavorDimensions "client"
productFlavors {
    company1{
        dimension "client"
        buildConfigField("String", "BASE_URL_DOMAIN", "\"https://app.company1/\"")
    }

    company2 {
        dimension "client"
        buildConfigField("String", "BASE_URL_DOMAIN", "\"https://app.company2/\"")
    }
}

И используйте его как:

Строка BASE_URL = BuildConfig.BASE_URL_DOMAIN + BuildConfig.BASE_URL_PATH

person Housefly    schedule 15.01.2019
comment
Спасибо за ответ. В некоторых случаях это сработает, но в моем случае мне нужен BASE_URL вместе. Этот URL не зависит от нас и может быть company1.com/apiDebug или debug.company2.com/api. - person kike; 15.01.2019
comment
Моя идея состоит в том, чтобы разделить весь URL на части и поместить их в Flavors и BuildTypes. Это работает, даже если есть комбинация с более чем двумя типами. то есть что-то вроде Company1-Mobile-Debug, Company2-Tablet-Prod и т. д. Если вы говорите, что здесь все неясно, то вам лучше использовать строковые константы в Java и использовать Build Type и Product Flavors вместе с некоторым оператором Switch для создания фактический URL во время выполнения - person Housefly; 15.01.2019

Вот рабочий пример

// Задает одно измерение вкуса.

flavorDimensions "version"

productFlavors {
dev {
    dimension "version"
    applicationId "com.example.lk"
    versionCode 1
    versionName "1.0.1"
    buildConfigField("String", "BASE_URL_PATH", "\"https://app.dev.com/api/v1/\"")
}

prod {
    dimension "version"
    applicationId "com.example.in"
    versionCode 1
    versionName "1.0.1"
    buildConfigField("String", "BASE_URL_PATH", "\"https://app.prod.com/api/v1/\"")

}
staging {
    dimension "version"
    applicationId "com.example.other"
    versionCode 1
    versionName "1.0.1"
    buildConfigField("String", "BASE_URL_PATH", "\"https://app.staging.com/api/v1/\"")

}}




buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
  }

вы можете получить к нему доступ следующим образом

String baseURL =BuildConfig.BASE_URL_PATH;
person Tufan    schedule 15.01.2019
comment
Ваше решение довольно крутое. Могу ли я сохранить значение URL-адреса в другом файле свойств, скажем, например: config.properties в корневой папке, и передать это значение в параметр значения buildConfig, будет ли это работать? На данный момент я попробовал этот подход и столкнулся с проблемой . размещено в стеке stackoverflow.com/q/67000811/1921204 - person MohanRaj S; 08.04.2021

Вы можете использовать варианты, чтобы добавить базовые конфигурации для вашего приложения, которые варьируются от app url, API keys, master password и т. д.

flavorDimensions "Mobile"
     productFlavors {
        Production {
            dimension "Mobile"   // dimension can be mobile, kiosks, tv, miniKiosks etc

            resValue "string", "API_KEY", "Just to give the idea"
            resValue "string", "SERVICE_IP", "Your service IP"
            resValue "string", "SERVICE_BASE_URL", ""
            resValue "string", "APK_BASE_URL", "base url"
            resValue "string", "MASTER_PASSWORD", ""

        }
        Demo {
            dimension "Mobile"

            resValue "string", "API_KEY", "Just to give the idea"
            resValue "string", "SERVICE_IP", "Your service IP"
            resValue "string", "SERVICE_BASE_URL", "services/v1/"
            resValue "string", "APK_BASE_URL", "base url"
            resValue "string", "MASTER_PASSWORD", ""
        }

    Local {
            dimension "Mobile"

            resValue "string", "API_KEY", ""
//            resValue "string", "app_name", ""
            resValue "string", "SERVICE_IP", ""
//            resValue "string", "SERVICE_IP", ""
            resValue "string", "SERVICE_BASE_URL", ""
            resValue "string", "APK_BASE_URL", ""
            resValue "string", "MASTER_PASSWORD", "a"
        }
    }

Теперь, если вы проверите свой build varients, вы получите что-то вроде этого:

введите здесь описание изображения

person Umair    schedule 15.01.2019

Ваша основная проблема заключается в том, что вы неправильно размещаете свои типы сборки для вкусов и не используете правильные параметры внутри каждой компании, а также я предлагаю вам больше узнать о настройках Gradle (developer.android).

    buildTypes {
        debug {
            // some configurations
        }
        release {
            // some configurations
        }
    }

    flavorDimensions "version", "brand"
    productFlavors {
        dev {
            versionName += "dev"
            dimension "version"

            buildConfigField "String", "BASE_API_URL", "\...\""
        }

        prod {
            dimension "version"

            buildConfigField "String", "BASE_API_URL", "\...\""
        }
        company1{
            dimension "brand"
            versionName "1.0.0"
            buildConfigField("int", "CLONE_ID", "1")
            **here you can set some params, for current clone id: examlpe ->** buildConfigField("boolean", "SHOW_CREDIT_BUY_IN_PROFILE", "true")
        }

        company2 {
            dimension "brand" 
            versionName "1.0.0"
            buildConfigField("int", "CLONE_ID", "2")
            **here you can set some params, for current clone id: examlpe ->** buildConfigField("boolean", "SHOW_CREDIT_BUY_IN_PROFILE", "false")


    }
person Pavel Petkevich    schedule 15.01.2019