Android App Development
Android Build Types ve Product Flavors
Ocak 16, 2023
Bu makalede, Android’de Build Types ve Product Flavors yapılarının kullanım detaylarını ve aralarındaki farkları ele alacağım. Her iki yapı da Android uygulamaları geliştirirken birçok kolaylık sağlamaktadır. Uygulamaların ikonlarından üretim versiyonlarına, geliştirme modu için özel konfigürasyonlardan uygulamanın farklı varyantlarını oluşturmaya kadar pek çok noktada bu yapılardan faydalanabiliriz.
Android Build Types
Build Types; uygulamaları geliştirirken, derlerken ve imzalı versiyonlarını hazırlarken Gradle tarafından kullanılan belirli özellikleri özelleştirmemize yardımcı olur. Ayrıca kullanacağımız bazı konfigürasyonları yönetmemizi de kolaylaştırır. Varsayılan olarak, yeni oluşturulan Android projelerinde iki adet Build Type tanımlıdır: biri debug modu, diğeri ise release modudur.

Yeni bir tip ekleyebiliriz. Bu tiplere bağlı olarak farklı versiyon uzantıları veya tamamen özel değişkenler eklememiz mümkündür. Geliştirme sırasında, Android Studio’nun sol alt köşesinde bulunan Build Variants sekmesini bir kısayol olarak kullanarak bu farklı tipler arasında kolayca geçiş yapabilirsiniz.

Kod derlendikten sonra, otomatik olarak oluşturulan BuildConfig.java sınıfı içerisindeki MODE değişkeni seçilen tipe göre güncellenir. Kod blokları içinden bu statik değişkenlere kolayca erişebilirsiniz. Environment değişikliklerinizi de burada uygulayabilirsiniz. Bu esneklik sayesinde, geliştirme modu için özel konfigürasyonlar kullanarak daha güvenli ve esnek bir geliştirme ortamı kurabilirsiniz.
buildTypes {
debug {
signingConfig signingConfigs.debug
shrinkResources false
minifyEnabled = false
debuggable true
resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY_DEBUG") ?: "")
buildConfigField "MODE", "DEBUG"
ext.betaDistributionReleaseNotesFilePath = "release_notes.txt"
ext.betaDistributionEmailsFilePath = "testers.txt"
ndk {
abiFilters "x86", "armeabi-v7a", "arm64-v8a"
}
}
release {
signingConfig signingConfigs.release
shrinkResources true
minifyEnabled true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
buildConfigField "MODE", "PROD"
ext.betaDistributionReleaseNotesFilePath = "release_notes.txt"
ext.betaDistributionEmailsFilePath = "testers.txt"
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
}
pilot {
debuggable = true
signingConfig signingConfigs.debug
debuggable true
resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
ext.betaDistributionReleaseNotesFilePath = "release_notes.txt"
ext.betaDistributionEmailsFilePath = "testers.txt"
buildConfigField "MODE", "PILOT"
ndk {
abiFilters "x86", "armeabi-v7a", "arm64-v8a"
}
}
}
Product Flavors
Product Flavors, Build Types yapısına benzer şekilde esneklik sağlayan bir yapıdır. Temel farkı, paylaşılan tek bir kod tabanından (shared codebase) uygulamanın farklı versiyonlarını üretmemize olanak tanımasıdır.
Android Product Flavors, bir uygulamanın farklı versiyonlarını oluşturmak için kullanılır. Bu versiyonlar, ücretsiz veya ücretli olma, farklı tema ve metinler barındırma ya da farklı environment veya API’leri kullanma gibi farklı özelliklere sahip olabilir. Örneğin, aynı uygulamanın hem ücretli hem de ücretsiz bir versiyonunu, aralarında sadece küçük farklar olacak şekilde oluşturmak istiyorsunuz. Her uygulama için ayrı bir kod tabanı kullanmak yerine, Product Flavors yapısını kullanarak paylaşılan bir kod tabanı üzerinden birden fazla versiyon oluşturabilirsiniz. Product Flavors ile uygulamanın isminden ikonuna, versiyon bilgisinden kullanılacak API environment yapısına kadar birçok özelliği kolayca yönetebilirsiniz.
flavorDimensions "env", "api"
productFlavors {
prod {
dimension "env"
resValue "string", "app_name", '"Production"'
manifestPlaceholders = [
appIcon: "@mipmap/ic_launcher",
appIconRound: "@mipmap/ic_launcher_round"
]
applicationIdSuffix ".release"
buildConfigField "String", "FLAVOR_TYPE", '"PRODUCTION"'
buildConfigField "String", "DATABASE", '"PRODUCTION_DB"'
}
test {
dimension "env"
resValue "string", "app_name", '"Test"'
manifestPlaceholders = [
appIcon: "@mipmap/ic_launcher_test",
appIconRound: "@mipmap/ic_launcher_test_round"
]
applicationIdSuffix ".test"
buildConfigField "String", "FLAVOR_TYPE", '"test"'
buildConfigField "String", "DATABASE", '"TEST_DB"'
}
minApi28 {
dimension "api"
minSdkVersion 23
versionCode 10000 + defaultConfig.versionCode
versionNameSuffix "-minApi28"
}
minApi24 {
dimension "api"
minSdkVersion 21
versionCode 10000 + defaultConfig.versionCode
versionNameSuffix "-minApi24"
}
}
Yukarıda paylaşılan kod mantığı hakkında açıklamak istediğim birkaç nokta var. İlk olarak, Flavor Dimensions ile “env” ve “api” olmak üzere iki adet dimension tanımlanmıştır. Bu özellik sayesinde, bu dimension’lar bazında gruplama yapabilir ve bunların kombinasyonlarını kullanabiliriz. Yani, yukarıdaki yapılandırma ile build.gradle dosyasını ilk kez derlediğimizde, “env” ve “api” grupları arasındaki kombinasyonun sonucu Build Variants sekmesinde görünecektir. Örneğin, test varyantı ile Minimum Api 24 varyantını birleştirerek yeni bir varyant versiyonu elde ederiz. Bu sayede, aynı kod tabanı ile API 24 ve 28 için ayrı düzenlemeler yapabilir, bunları ayrı ayrı dağıtabilir ve yönetebiliriz. “res_value” parametresi ile uygulamaların isimlerini birbirinden farklılaştırabiliriz. “manifest placeholders” parametresi ile uygulama ikonlarını da farklı şekillerde kullanabiliriz. Manifest placeholders ile uygulama adını değiştirmek de mümkündür.
Product Flavors yapısı, Build Types yapısında olduğu gibi özel değişkenler tanımlamanıza da olanak tanır. Benzer şekilde, bu statik değişkenlere BuildConfig.java sınıfı üzerinden erişebilirsiniz.
Yazar: Erdi Koç