Build Variant — Android’de build type ve product flavor nedir

Yazar: IT Sectr Yayınlanma: 2026-05-30 Okuma süresi: 9 dk

Android geliştirmede Build Variant, bir build type ve bir product flavor’ın birleşimidir ve bir APK veya AAB’nin hangi parametrelerle, kaynaklarla ve kodla oluşturulacağını belirler. Her derleme varyantı, kendi applicationId’si, imzalama anahtarları ve dahil edilen bağımlılıklarıyla ayrı bir Gradle yapılandırmasını temsil eder. Google Android Developers, 2025’a göre, Build Variants’ın doğru yapılandırılması, her varyant için gereksiz kaynakları hariç tutarak derleme süresini %40’a kadar azaltır. Derleme varyantı sistemi, modern Android projelerinde yapılandırma yönetiminin temelidir.

Önemli Noktalar

  • Build Variant — bir Build Type ve bir Product Flavor’ın birleşimi.
  • Build Type derleme modunu tanımlar: debug veya release.
  • Product Flavor uygulama sürümünü tanımlar: free, paid, demo, enterprise.
  • Gradle her Build Variant için install ve assemble dahil olmak üzere otomatik olarak görevler oluşturur.
  • Kaynaklar ve kod ilgili source set’ler aracılığıyla her varyant için geçersiz kılınabilir.

Build Variant Nedir?

Build Variant, bir Build Type ile bir Product Flavor’ın birleştirilmesinin sonucudur. Projede hiçbir Product Flavor tanımlanmamışsa, Build Variant Build Type ile eşleşir. Gradle, tüm FlavorDimensions, Product Flavors ve Build Types’ın Kartezyen çarpımı olarak varyantların tam kümesini otomatik olarak oluşturur. Örneğin, free/paid flavor’lar ve debug/release türleri için 4 varyant oluşturulur: freeDebug, freeRelease, paidDebug, paidRelease.

Her Build Variant, flavor büyük harfle başlayacak şekilde <Flavor><Type> formatında kendi adını alır. Gradle bu varyant için ayrı görevler oluşturur: assembleFreeDebug, installFreeDebug, bundleFreeRelease. Android Studio’da, Build Variants paneli (View → Tool Windows → Build Variants) aracılığıyla varyantlar arasında geçiş yapılabilir. Bir varyant seçmek, hangi kodun derleneceğini, hangi kaynakların dahil edileceğini ve hangi APK/AAB’nin üretileceğini etkiler.

Build Variants sistemi üç temel görevi çözer: farklı ortamlar (dev/staging/production) için yapılandırmaları ayırmak, bir uygulamanın birden çok sürümünü (free/paid) oluşturmak ve derlemelerin A/B testini yapmak. Build Variants olmadan, geliştiricilerin manuel olarak bayrakları ve yapılandırmaları değiştirmesi gerekir ve bu da insan hatasına yol açar. Gradle Inc., 2024 tarafından yapılan bir araştırmaya göre, Build Variants’ın uygulanması, üç veya daha fazla dağıtım ortamına sahip projelerde derleme hatalarını %60 oranında azaltır.

Gradle Varyantları Nasıl Oluşturur

AGP (Android Gradle Plugin) yapılandırma aşamasında tüm kombinasyonları hesaplar. Bir projenin sırasıyla iki ve üç flavor’a sahip iki boyutu varsa, Gradle 2 × 2 × 3 = 12 kombinasyon oluşturur ve bu da Build Types sayısıyla (genellikle 2) çarpılır. Her kombinasyon benzersiz bir ad ve görev kümesi alır. AGP her varyant için otomatik olarak bir source set ekler: src/freeDebug/, src/paidRelease/ ve genelleştirilmiş src/free/ ile src/debug/. Kaynak okuma önceliği: variant → flavor → type → main.

groovy
// Örnek: 4 Build Variants
// flavorDimensions "version", "server"
// version: demo, prod
// server: mock, live
// buildTypes: debug, release
// Toplam: 2 × 2 × 2 = 8 varyant

android {
    flavorDimensions "version", "server"

    productFlavors {
        demo { dimension "version" }
        prod { dimension "version" }
        mock { dimension "server" }
        live { dimension "server" }
    }
}

Build Type ve Product Flavor: Farklar

Build Type, uygulamanın nasıl derleneceğini tanımlar — hata ayıklama bilgisiyle veya olmadan, optimizasyonla veya olmadan, hangi imzayla. Product Flavor neyin derleneceğini tanımlar — ürünün hangi sürümünü. Build Type bir derleme mekanizmasıdır (debug, release, staging). Product Flavor bir ürün varyantıdır (free, paid, enterprise, demo). Her iki kavram da ortogonaldir: herhangi bir Build Type herhangi bir Product Flavor’a uygulanabilir.

Varsayılan Build Type’lar debug (debuggable=true, minification=false, signing=debug.keystore) ve release’i (debuggable=false, minification=true, signing=production.keystore) içerir. Varsayılan Product Flavor birdir ve adsızdır (etkin olarak main source set). Geliştiriciler kendi Build Type’larını (örneğin, debuggable=true ve minification=true olan “staging”) ve istedikleri sayıda Product Flavor’ı ekleyebilir. Diğer bir fark, Build Type’ların boyutlara göre gruplandırılamaması, ancak Product Flavor’ların gruplandırılabilmesidir.

Temel pratik fark: build.gradle’daki defaultConfig tüm Variants’lara uygulanır ancak productFlavors ve buildTypes içinde geçersiz kılınabilir. Bir buildType’a eklenen BuildConfigField, o türdeki tüm flavor’larda görünürken, bir productFlavor’a eklenen, o flavor’un tüm türlerinde görünür. Bir alan her ikisinde de tanımlanmışsa, buildType önceliklidir (zincirde en son uygulanır).

Karşılaştırma Tablosu

ÖzellikBuild TypeProduct Flavor
AmaçNasıl derleneceğiNeyin derleneceği
Örneklerdebug, release, stagingfree, paid, demo, enterprise
Varsayılandebug + releasebir (main)
Source Setsrc/debug/, src/release/src/free/, src/paid/
BoyutlarhayırflavorDimensions
Uygulama sırasıflavor’dan sonra, geçersiz kılardefaultConfig’ten sonra
BuildConfigFieldflavor’ı geçersiz kılardefaultConfig’i geçersiz kılar

build.gradle’da Build Variants Yapılandırması

Yapılandırma Önceliği

Build Variants yapılandırması, modül düzeyindeki build.gradle dosyasının android bloğunda yapılır. Önce buildTypes parametreleriyle birlikte bildirilir, ardından flavorDimensions ve productFlavors. Gradle bu bildirimlere dayanarak varyantları otomatik olarak oluşturur. Her varyant, modülün defaultConfig’ini devralır ve belirtilen alanları geçersiz kılar. Bildirim sırası önceliği etkiler: buildTypes, productFlavors’tan sonra uygulanır.

Gradle betiklerinde belirli bir Build Variant’a erişmek için android.applicationVariants (app modülleri için) veya android.libraryVariants (kütüphane modülleri için) kullanın. Bu, yapılandırma çalışma zamanında her varyantın yapılandırmasını değiştirmek için yinelenebilen bir koleksiyondur. Örneğin, “demo” kelimesini içeren tüm varyantlar için programlama yoluyla buildConfigField ekleyebilirsiniz.

Android Gradle Plugin 8.x, lambda’lar aracılığıyla varyantları yapılandırmak için daha temiz bir API olan onVariants desteğini ekledi. Eski API (variantOutput, variantFilter) kullanımdan kaldırıldı olarak işaretlendi. Kütüphane modülleri için onEach ile birlikte onVariants kullanılması önerilir. variantOutput’tan onVariants’a geçiş, AGP’yi 7.x’ten 8.x’e yükseltirken önerilen bir adımdır.

groovy
android {
    buildTypes {
        debug {
            debuggable true
            minification false
            signingConfig signingConfigs.debug
        }
        release {
            debuggable false
            minification true
            proguardFiles "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
        staging {
            debuggable true
            minification true
            versionNameSuffix "-staging"
        }
    }

    flavorDimensions "tier", "region"

    productFlavors {
        free { dimension "tier" }
        paid { dimension "tier" }
        us { dimension "region" }
        eu { dimension "region" }
    }
}

android.onVariants { variant ->
    if (variant.name.contains("Demo")) {
        variant.setEnabled(false)
    }
}

Source Set’ler ve Kaynak Geçersiz Kılma

Her Build Variant, kendi source set hiyerarşisini alır — kaynak kodu, kaynaklar ve bildirim içeren dizinler. Bir source set src/<variantName>/ konumunda bulunur (örneğin, src/freeDebug/) ve java/, res/, AndroidManifest.xml, assets/ içerebilir. Varyantın source set’inde bir dosya varsa, ana source set’ten (src/main/) aynı ada sahip dosyayı geçersiz kılar. Kaynaklar için değiştirme yerine birleştirme gerçekleşir — sistem, tüm etkin source set’lerden kaynakları birleştirir ve varyanta özgü olanlara öncelik verir.

Bir Build Variant için source set’ler bir zincir halinde oluşturulur: src/main/src/flavor/src/type/src/flavorType/. Örneğin, paidRelease için önce main, ardından paid, sonra release ve en son paidRelease uygulanır. Sonraki her source set bir öncekini geçersiz kılar. Bu, src/release/res/values/strings.xml’in src/paid/ şıkkındaki aynı dizeleri geçersiz kılacağı, ancak src/paidRelease/res/ şıkkının daha da yüksek önceliğe sahip olduğu anlamına gelir.

Varyantlar için source set kullanmak, kaynakları özelleştirmenin önerilen yoludur. Kodda BuildConfig.FLAVOR’u kontrol edip mantığı dallandırmak yerine, farklı dosyaları farklı source set’lere yerleştirebilirsiniz. Örneğin, free ve paid sürümlerinin simgeleri sırasıyla src/free/res/ ve src/paid/res/ içine, farklı izinlere sahip AndroidManifest ise src/free/AndroidManifest.xml ve src/paid/AndroidManifest.xml içine konur. Bu daha temiz, daha hızlıdır (kaynaklar derlenir, çalışma zamanında kontrol edilmez) ve daha güvenlidir (kod hatası nedeniyle ücretsiz sürüme yanlışlıkla ücretli işlevsellik ekleyemezsiniz).

Çok Modüllü Projelerde Build Variant

Çok modüllü projelerde, her modül (kütüphane) kendi Build Variants’ına sahip olabilir. AGP varyantları otomatik olarak senkronize eder: app modülü paidRelease oluşturursa, bağımlı tüm kütüphaneler de paidRelease’e karşılık gelen varyantlarında oluşturulur. Bir kütüphanede product flavor yoksa ancak app modülünde varsa sorun ortaya çıkar — bu durumda kütüphane bir kez (türüne göre release veya debug) oluşturulur.

Kütüphane modülleri için Build Variant varsayılan olarak app modülünün Build Type‑ıyla eşleşir, çünkü kütüphanelerde product flavor bulunmaz. Bir kütüphanenin app modülünün flavor’ına uyum sağlaması gerekiyorsa, aynı flavorDimensions ve productFlavors kütüphanede bildirilmelidir. AGP, flavor’ları tam ad eşleşmesiyle eşleştirir. Gradle, kök projede subprojects veya Convention Plugins kullanarak derleme yapılandırması aracılığıyla flavor’ları senkronize etmeyi önerir.

AGP 8.1’den itibaren kütüphaneler birden çok varyant yayınlayabilir — tüm kütüphane varyantlarını aynı anda bir maven deposuna yayınlayabilir. Bu, app modülünün ücretli bir flavor kullanması ancak kütüphanenin yalnızca ücretsiz için yayınlanması sorununu çözer. Birden çok varyant yayınlama (MVP), bağımlı projenin gerekli varyantı otomatik olarak seçmesine olanak tanır. MVP’yi etkinleştirmek için kütüphanenin build.gradle’ına publishing { multipleVariants { ... } } ekleyin.

Varyantları Filtreleme ve Devre Dışı Bırakma

CI/CD ile Dinamik Filtreleme

Bazen bazı Build Variants’ları devre dışı bırakmak gerekebilir — örneğin, mockRelease kombinasyonu anlamlı değilse (mock sunucu üretime gönderilmemelidir). Gradle, her varyantın özelliklerini kontrol edebileceğiniz ve setIgnore(true) ile devre dışı bırakabileceğiniz bir DSL bloğu olan variantFilter’ı sağlar. VariantFilter, görev oluşturmadan önce yapılandırma aşamasında uygulanır, bu nedenle devre dışı bırakılan bir varyant assemble ve install görevleri üretmez.

Filtreleme, derlemeleri hızlandırmak için de kullanışlıdır. Bir projede 8 varyant varsa ancak bir geliştirici yalnızca birinde çalışıyorsa, kalan 7 varyant yine de yapılandırmadan geçer. variantFilter kullanıldığında, devre dışı bırakılan varyantlar görev oluşturmaz ve 6+ flavor boyutuna sahip projelerde yapılandırma süresini %30-50 oranında azaltır. CI/CD’de, komut satırı parametreleri -PbuildOnly=paidRelease aracılığıyla varyantları dinamik olarak filtreleyebilirsiniz.

groovy
android {
    variantFilter { variant ->
        // release için mock’u ve production için demo’yu devre dışı bırak
        def names = variant.flavors*.name
        def isMock = names.contains("mock")
        def isDemo = names.contains("demo")
        def isRelease = variant.buildType.name == "release"

        if ((isMock && isRelease) || (isDemo && !isMock)) {
            variant.setIgnore(true)
        }
    }
}

// Parametrelerle dinamik filtreleme
if (project.hasProperty("buildOnly")) {
    def target = project.property("buildOnly")
    android.variantFilter { variant ->
        variant.setIgnore(variant.name != target)
    }
}

Sıkça Sorulan Sorular

Kaç tane Build Variants oluşturulabilir?

Bir sınır yoktur, ancak Gradle tüm flavor’ların ve türlerin Kartezyen çarpımını oluşturur. 3 boyutun her birinde 3 flavor ve 3 build type varsa, 27 varyant elde edersiniz. Çok fazla varyant yapılandırmayı yavaşlatır. Bir modülte 10–12’den fazla varyant olmaması önerilir.

flavorDimensions neden gereklidir?

flavorDimensions, Product Flavors’ı bağımsız eksenler halinde gruplandırır. Örneğin, “tier” boyutu (free, paid) ve “region” boyutu (us, eu). Boyutlar olmadan, tüm flavor’lar tek bir eksene aittir ve Gradle tümünden yalnızca bir flavor seçer (free+us ve paid+eu’yu ayrı varyantlar olarak sahip olamazsınız).

Bir varyant için applicationId nasıl geçersiz kılınır?

productFlavor veya buildType bloğunda applicationId belirtin. Örneğin, ücretsiz sürüm için: free { applicationId “com.example.app.free” }. Bildirimde ${applicationId} kullanın — Gradle değeri otomatik olarak değiştirecektir. Bu, her iki varyantın da aynı cihaza yüklenmesine olanak tanır.

iOS’te Build Variants kullanılabilir mi?

iOS’te, Build Variants’ın eşdeğeri Scheme + Configuration kombinasyonudur. Xcode Schemes, farklı parametrelerle Debug/Release yapılandırmaları aracılığıyla yapılandırılır. Birden çok sürüm (free/paid) için Build Configurations ve Preprocessor Macros kullanılır. Android’de konsept daha resmidir ve Gradle’a yerleşiktir.

Build Variant APK boyutunu etkiler mi?

Evet, her varyant farklı APK boyutuna sahip olabilir. Debug derlemeleri hata ayıklama bilgilerini, SDK’yı ve desteklenmeyen kaynakları içerir. Minification ve resource shrinking ile release derlemeleri minimum boyut üretir. Product Flavor da boyutu etkiler: ücretsiz kitaplıkları olmayan ücretsiz sürüm, bu kitaplıkların boyutu kadar ücretli sürümden daha küçük olacaktır.

Özet

  • Build Variant — derleme yapılandırmasını tanımlayan bir Build Type ve bir Product Flavor’ın birleşimi.
  • Build Type derleme modunu (debug/release/staging) kontrol ederken, Product Flavor ürün sürümünü (free/paid) kontrol eder.
  • Source set’ler her derleme varyantı için kod, kaynak ve bildirimi geçersiz kılmaya olanak tanır.
  • VariantFilter gereksiz kombinasyonları devre dışı bırakarak Gradle yapılandırmasını %30–50 hızlandırır.
  • Çok modüllü projeler tüm modüllerde flavor senkronizasyonu veya birden çok varyant yayınlama gerektirir.
  • BuildConfigField ve source set’ler, varyantlar arasında davranışı özelleştirmenin iki temiz yoludur.
  • Öneri: bir projede 10–12’den fazla varyant oluşturmayın; boyutları anlamlı bir şekilde gruplandırın.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun