Bu sayfada, tek bir projeden uygulamanızın farklı sürümlerini oluşturmak için derleme varyantlarını nasıl yapılandırabileceğiniz ve bağımlılıklarınızı ve imzalama yapılandırmalarınızı nasıl düzgün şekilde yönetebileceğiniz gösterilmektedir.
Her derleme varyantı, derleyebileceğiniz uygulamanızın farklı bir sürümünü temsil eder. Örneğin, uygulamanızın sınırlı içerik içeren ücretsiz bir sürümünü ve daha fazla içerik barındıran ücretli bir sürümünü oluşturabilirsiniz. Ayrıca, API düzeyine veya diğer cihaz varyasyonlarına göre uygulamanızın farklı cihazları hedefleyen farklı sürümlerini de derleyebilirsiniz.
Derleme varyantları, Gradle'in derleme türlerinizde ve ürün lezzetlerinizde yapılandırılmış ayarları, kodu ve kaynakları birleştirmek için belirli bir kural grubu kullanmasının sonucudur. Derleme çeşitlerini doğrudan yapılandırmasanız da bunları oluşturan derleme türlerini ve ürün varyantlarını yapılandırırsınız.
Örneğin, "demo" ürün çeşidi özel kaynak kodu, kaynaklar ve minimum API seviyeleri gibi belirli özellikleri ve cihaz şartlarını belirtebilir. "Hata ayıklama" derleme türü ise hata ayıklama seçenekleri ve imzalama anahtarları gibi farklı derleme ve paketleme ayarları uygular. Bu ikisini birleştiren derleme varyantı, uygulamanızın "demoDebug" sürümüdür ve "demo" ürün çeşidi, "debug" derleme türü ve main/
kaynak kümesine dahil edilen yapılandırmaların ve kaynakların bir kombinasyonunu içerir.
Derleme türlerini yapılandırma
Modül düzeyindeki build.gradle.kts
dosyasının android
bloğunda derleme türleri oluşturabilir ve yapılandırabilirsiniz. Yeni bir modül oluşturduğunuzda Android Studio, hata ayıklama ve sürüm derleme türlerini otomatik olarak oluşturur. Hata ayıklama derleme türü derleme yapılandırma dosyasında görünmese de Android Studio bu türü debuggable
true
ile yapılandırır. Bu işlem, uygulamada güvenli Android cihazlarda hata ayıklamanıza olanak tanır ve uygulama imzalamayı genel bir hata ayıklama anahtar deposuyla yapılandırır.
Belirli ayarları eklemek veya değiştirmek istiyorsanız yapılandırmanıza hata ayıklama derleme türünü ekleyebilirsiniz. Aşağıdaki örnekte, hata ayıklama derleme türü için bir
applicationIdSuffix
belirtilmiş ve hata ayıklama derleme türünün ayarları kullanılarak başlatılan bir "hazırlama" derleme türü yapılandırılmıştır:
Kotlin
android { defaultConfig { manifestPlaceholders["hostName"] = "www.example.com" ... } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } getByName("debug") { applicationIdSuffix = ".debug" isDebuggable = true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ create("staging") { initWith(getByName("debug")) manifestPlaceholders["hostName"] = "internal.example.com" applicationIdSuffix = ".debugStaging" } } }
Groovy
android { defaultConfig { manifestPlaceholders = [hostName:"www.example.com"] ... } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix ".debug" debuggable true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ staging { initWith debug manifestPlaceholders = [hostName:"internal.example.com"] applicationIdSuffix ".debugStaging" } } }
Not: Bir derleme yapılandırma dosyasında değişiklik yaptığınızda Android Studio, projenizi yeni yapılandırmayla senkronize etmenizi gerektirir. Projenizi senkronize etmek için değişiklik yaptığınızda görünen bildirim çubuğunda Şimdi Senkronize Et'i veya araç çubuğundan Projeyi Senkronize Et'i tıklayın. Android Studio, yapılandırmanızda hata olduğunu fark ederse sorunu açıklayan Mesajlar penceresi gösterilir.
Derleme türleriyle yapılandırabileceğiniz tüm özellikler hakkında daha fazla bilgi edinmek için
BuildType
referansını okuyun.
Ürün varyantlarını yapılandırma
Ürün varyantları oluşturma, derleme türleri oluşturmaya benzer. Derleme yapılandırmanızdaki productFlavors
bloğuna ürün varyantları ekleyin ve istediğiniz ayarları ekleyin.
Ürün varyantları, defaultConfig
aslında
ProductFlavor
sınıfına ait olduğu için defaultConfig
ile aynı özellikleri destekler. Bu, defaultConfig
bloğundaki tüm varyantlar için temel yapılandırmayı sağlayabileceğiniz ve her varyantın bu varsayılan değerlerden herhangi birini (ör. applicationId
) değiştirebileceği anlamına gelir. Uygulama kimliği hakkında daha fazla bilgi edinmek için Uygulama kimliğini ayarlama başlıklı makaleyi inceleyin.
Not: main/
manifest dosyasında package
özelliğini kullanarak bir paket adı belirtmeniz gerekir. R
sınıfına atıfta bulunmak veya ilgili etkinlik ya da hizmet kaydını çözmek için kaynak kodunuzda bu paket adını da kullanmanız gerekir. Bu sayede, kaynak kodunuzu değiştirmek zorunda kalmadan her ürüne paketleme ve dağıtım için benzersiz bir kimlik vermek üzere applicationId
kullanabilirsiniz.
Tüm aromalar, ürün aromaları grubu olan adlandırılmış bir aroma boyutuna ait olmalıdır. Tüm lezzetleri bir lezzet boyutuna atamanız gerekir. Aksi takdirde aşağıdaki derleme hatasını alırsınız.
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
Belirli bir modül yalnızca bir lezzet boyutu belirtiyorsa Android Gradle eklentisi, modülün tüm lezzetlerini o boyuta otomatik olarak atar.
Aşağıdaki kod örneği, "version" adlı bir tat boyutu oluşturur ve "demo" ile "full" ürün tatlarını ekler. Bu aromalar kendi
applicationIdSuffix
ve
versionNameSuffix
özelliklerini sağlar:
Kotlin
android { ... defaultConfig {...} buildTypes { getByName("debug"){...} getByName("release"){...} } // Specifies one flavor dimension. flavorDimensions += "version" productFlavors { create("demo") { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension = "version" applicationIdSuffix = ".demo" versionNameSuffix = "-demo" } create("full") { dimension = "version" applicationIdSuffix = ".full" versionNameSuffix = "-full" } } }
Groovy
android { ... defaultConfig {...} buildTypes { debug{...} release{...} } // Specifies one flavor dimension. flavorDimensions "version" productFlavors { demo { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension "version" applicationIdSuffix ".demo" versionNameSuffix "-demo" } full { dimension "version" applicationIdSuffix ".full" versionNameSuffix "-full" } } }
Not: Google Play'de APK'ları kullanarak dağıttığınız eski bir uygulamanız (Ağustos 2021'den önce oluşturulmuş) varsa uygulamanızı Google Play'de çoklu APK desteği ile dağıtmak için tüm varyantlara aynı applicationId
değerini atayın ve her varyanta farklı bir versionCode
atayın. Uygulamanızın farklı varyantlarını Google Play'de ayrı uygulamalar olarak dağıtmak için her varyanta farklı bir applicationId
atamanız gerekir.
Ürün varyantlarınızı oluşturup yapılandırdıktan sonra bildirim çubuğunda Şimdi senkronize et'i tıklayın. Senkronizasyon tamamlandıktan sonra Gradle, derleme türlerinize ve ürün yapılarınıza göre otomatik olarak derleme varyantları oluşturur ve bunları <product-flavor><Build-Type>
'ye göre adlandırır. Örneğin, "demo" ve "full" ürün aromaları oluşturduysanız ve varsayılan "debug" ve "release" derleme türlerini koruduysanız Gradle aşağıdaki derleme varyantlarını oluşturur:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
Hangi derleme varyantının oluşturulup çalıştırılacağını seçmek için Derle > Derleme Varyantı Seç'e gidin ve menüden bir derleme varyantı seçin. Her derleme varyantını kendi özellikleri ve kaynaklarıyla özelleştirmeye başlamak için bu sayfada açıklandığı gibi kaynak kümeleri oluşturmanız ve yönetmeniz gerekir.
Derleme varyantlarının uygulama kimliğini değiştirme
Uygulamanız için APK veya AAB oluşturduğunuzda derleme araçları, uygulamayı aşağıdaki örnekte gösterildiği gibi build.gradle.kts
dosyasının defaultConfig
bloğunda tanımlanan uygulama kimliğiyle etiketler. Ancak, Google Play Store'da ayrı girişler olarak görünecek farklı sürümler (ör. "ücretsiz" ve "pro" sürüm) oluşturmak istiyorsanız her biri farklı bir uygulama kimliğine sahip ayrı derleme varyantları oluşturmanız gerekir.
Bu durumda, her derleme varyantını ayrı bir ürün aroması olarak tanımlayın. productFlavors
bloğundaki her bir sürüm için applicationId
mülkünü yeniden tanımlayabilir veya bunun yerine burada gösterildiği gibi applicationIdSuffix
kullanarak varsayılan uygulama kimliğine bir segment ekleyebilirsiniz:
Kotlin
android { defaultConfig { applicationId = "com.example.myapp" } productFlavors { create("free") { applicationIdSuffix = ".free" } create("pro") { applicationIdSuffix = ".pro" } } }
Groovy
android { defaultConfig { applicationId "com.example.myapp" } productFlavors { free { applicationIdSuffix ".free" } pro { applicationIdSuffix ".pro" } } }
Bu şekilde, "ücretsiz" ürün çeşidinin uygulama kimliği "com.example.myapp.free" olur.
Derleme türünüze göre bir segment eklemek için applicationIdSuffix
simgesini de kullanabilirsiniz.
Kotlin
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
Groovy
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
Gradle, derleme türü yapılandırmasını ürün çeşidinden sonra uyguladığından "ücretsiz hata ayıklama" derleme varyantının uygulama kimliği "com.example.myapp.free.debug" olur. Hiçbir uygulamanın aynı uygulama kimliğine sahip olamayacağından, hem hata ayıklama hem de sürüm derlemesini aynı cihazda kullanmak istediğinizde bu seçenek faydalıdır.
Google Play'de APK'ları kullanarak dağıttığınız eski bir uygulamanız (Ağustos 2021'den önce oluşturulmuş) varsa ve her biri API düzeyi gibi farklı bir cihaz yapılandırmasını hedefleyen birden fazla APK dağıtmak için aynı uygulama listelemesini kullanmak istiyorsanız her derleme varyantı için aynı uygulama kimliğini kullanmalı ancak her APK'ya farklı birversionCode
vermelisiniz. Daha fazla bilgi için Birden fazla APK desteği hakkındaki makaleyi okuyun. Varsayılan olarak tek bir sürüm kodu ve uygulama kimliği kullanan tek bir yapı kullandığından, AAB'ler kullanılarak yapılan yayınlama bu durumdan etkilenmez.
İpucu: Manifest dosyanızda uygulama kimliğine referans vermeniz gerekiyorsa herhangi bir manifest özelliğinde ${applicationId}
yer tutucusunu kullanabilirsiniz. Gradle, derleme sırasında bu etiketi gerçek uygulama kimliğiyle değiştirir. Daha fazla bilgi için Derleme değişkenlerini manifest dosyasına ekleme bölümüne bakın.
Birden fazla ürün aromasını aroma boyutlarıyla birleştirme
Bazı durumlarda, birden fazla ürün çeşidine ait yapılandırmaları birleştirmek isteyebilirsiniz. Örneğin, API düzeyine dayalı "tam" ve "demo" ürün varyantları için farklı yapılandırmalar oluşturabilirsiniz. Android Gradle eklentisi, bunu yapmak için lezzet boyutları olarak birden fazla ürün lezzeti grubu oluşturmanıza olanak tanır.
Gradle, uygulamanızı oluştururken nihai derleme varyantını oluşturmak için tanımladığınız her lezzet boyutundaki ürün lezzeti yapılandırmasını ve derleme türü yapılandırmasını birleştirir. Gradle, aynı aroma boyutuna ait ürün aromalarını birleştirmez.
Aşağıdaki kod örneği, "tam" ve "demo" ürün türlerini gruplandırmak için "mod" tür boyutu oluşturmak amacıyla
flavorDimensions
mülkünü ve ürün türü yapılandırmalarını API seviyesine göre gruplandırmak için "api" tür boyutunu kullanır:
Kotlin
android { ... buildTypes { getByName("debug") {...} getByName("release") {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions += listOf("api", "mode") productFlavors { create("demo") { // Assigns this product flavor to the "mode" flavor dimension. dimension = "mode" ... } create("full") { dimension = "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. create("minApi24") { dimension = "api" minSdk = 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode = 30000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi24" ... } create("minApi23") { dimension = "api" minSdk = 23 versionCode = 20000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi23" ... } create("minApi21") { dimension = "api" minSdk = 21 versionCode = 10000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi21" ... } } } ...
Groovy
android { ... buildTypes { debug {...} release {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions "api", "mode" productFlavors { demo { // Assigns this product flavor to the "mode" flavor dimension. dimension "mode" ... } full { dimension "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. minApi24 { dimension "api" minSdkVersion 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode 30000 + android.defaultConfig.versionCode versionNameSuffix "-minApi24" ... } minApi23 { dimension "api" minSdkVersion 23 versionCode 20000 + android.defaultConfig.versionCode versionNameSuffix "-minApi23" ... } minApi21 { dimension "api" minSdkVersion 21 versionCode 10000 + android.defaultConfig.versionCode versionNameSuffix "-minApi21" ... } } } ...
Gradle'ın oluşturduğu yapı varyantlarının sayısı, her bir lezzet boyutundaki lezzetlerin sayısının ve yapılandırdığınız yapı türlerinin sayısının çarpımına eşittir. Gradle her bir derleme varyantını veya ilgili yapıları adlandırırken öncelikli tat boyutuna ait ürün tatlarını, ardından düşük öncelikli boyutlardaki tatları ve ardından derleme türünü gösterir.
Önceki derleme yapılandırmasını örnek olarak kullanan Gradle, aşağıdaki adlandırma şemasıyla toplam 12 derleme varyantı oluşturur:
- Derleme varyantı:
[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
- İlgili APK:
app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
- Örneğin,
- Derleme varyantı:
minApi24DemoDebug
- İlgili APK:
app-minApi24-demo-debug.apk
Her bir ürün çeşidi ve derleme varyantı için oluşturabileceğiniz kaynak kümesi dizinlerine ek olarak, ürün çeşidi kombinasyonları için de kaynak kümesi dizinleri oluşturabilirsiniz. Örneğin, src/demoMinApi24/java/
dizini oluşturabilir ve bu dizin içine Java kaynakları ekleyebilirsiniz. Gradle bu kaynakları yalnızca bu iki ürün çeşidini birleştiren bir varyant oluştururken kullanır.
Ürün çeşidi kombinasyonları için oluşturduğunuz kaynak setleri, her bir ürün çeşidine ait kaynak setlerinden daha yüksek önceliğe sahiptir. Kaynak kümeleri ve Gradle'in kaynakları nasıl birleştirdiği hakkında daha fazla bilgi edinmek için kaynak kümesi oluşturma ile ilgili bölümü okuyun.
Varyantları filtreleme
Gradle, yapılandırdığınız ürün lezzetleri ve derleme türlerinin her bir olası kombinasyonu için bir derleme varyantı oluşturur. Ancak, ihtiyacınız olmayan veya projeniz bağlamında anlamlı olmayan belirli derleme varyantları olabilir. Belirli derleme varyantı yapılandırmalarını kaldırmak için modül düzeyindeki build.gradle.kts
dosyanızda bir varyant filtresi oluşturun.
Önceki bölümdeki derleme yapılandırmasını örnek olarak kullanarak, uygulamanın demo sürümü için yalnızca API düzeyi 23 ve sonraki sürümleri desteklemeyi planladığınızı varsayalım. "minApi21" ve "demo" ürün aromalarını birleştiren tüm derleme varyantı yapılandırmalarını filtrelemek için
variantFilter
bloğunu kullanabilirsiniz:
Kotlin
android { ... buildTypes {...} flavorDimensions += listOf("api", "mode") productFlavors { create("demo") {...} create("full") {...} create("minApi24") {...} create("minApi23") {...} create("minApi21") {...} } } androidComponents { beforeVariants { variantBuilder -> // To check for a certain build type, use variantBuilder.buildType == "<buildType>" if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) { // Gradle ignores any variants that satisfy the conditions above. variantBuilder.enable = false } } } ...
Groovy
android { ... buildTypes {...} flavorDimensions "api", "mode" productFlavors { demo {...} full {...} minApi24 {...} minApi23 {...} minApi21 {...} } variantFilter { variant -> def names = variant.flavors*.name // To check for a certain build type, use variant.buildType.name == "<buildType>" if (names.contains("minApi21") && names.contains("demo")) { // Gradle ignores any variants that satisfy the conditions above. setIgnore(true) } } } ...
Derleme yapılandırmanıza bir varyant filtresi ekledikten ve bildirim çubuğunda Şimdi senkronize et'i tıkladıktan sonra Gradle, belirttiğiniz koşulları karşılayan tüm derleme varyantlarını yoksayar. Artık menü çubuğundan Derle > Derleme Varyantı Seç'i veya araç penceresi çubuğundan Derleme Varyantları'nı tıkladığınızda derleme varyantları menüde görünmez.
Kaynak kümeleri oluşturma
Android Studio varsayılan olarak, tüm derleme varyantlarınız arasında paylaşmak istediğiniz her şey için main/
kaynak grubunu ve dizinleri oluşturur. Ancak Gradle'ın belirli derleme türleri, ürün aromaları, ürün aromalarının kombinasyonları (aroma boyutları kullanılırken) ve derleme varyantları için tam olarak hangi dosyaları derleyip paketleyeceğini kontrol etmek üzere yeni kaynak kümeleri oluşturabilirsiniz.
Örneğin, main/
kaynak grubunda temel işlevleri tanımlayabilir ve farklı istemciler için uygulamanızın markasını değiştirmek üzere ürün aroması kaynak gruplarını kullanabilir ya da yalnızca hata ayıklama derleme türünü kullanan derleme varyantları için özel izinler ve günlük kaydı işlevi ekleyebilirsiniz.
Gradle, kaynak kümesi dosyalarının ve dizinlerinin main/
kaynak kümesine benzer şekilde belirli bir şekilde düzenlenmesini bekler. Örneğin, Gradle, "hata ayıklama" derleme türünüze özgü Kotlin veya Java sınıf dosyalarının src/debug/kotlin/
veya src/debug/java/
dizinlerinde bulunmasını bekler.
Android Gradle eklentisi, dosyalarınızı derleme türleriniz, ürün türleriniz ve derleme varyantlarınıza göre nasıl düzenleyeceğinizi gösteren kullanışlı bir Gradle görevi sağlar. Örneğin, görev çıktısından alınan aşağıdaki örnekte, Gradle'in "debug" derleme türü için belirli dosyaları nerede bulmayı beklediği açıklanmaktadır:
------------------------------------------------------------ Project :app ------------------------------------------------------------ ... debug ---- Compile configuration: debugCompile build.gradle name: android.sourceSets.debug Java sources: [app/src/debug/java] Kotlin sources: [app/src/debug/kotlin, app/src/debug/java] Manifest file: app/src/debug/AndroidManifest.xml Android resources: [app/src/debug/res] Assets: [app/src/debug/assets] AIDL sources: [app/src/debug/aidl] RenderScript sources: [app/src/debug/rs] JNI sources: [app/src/debug/jni] JNI libraries: [app/src/debug/jniLibs] Java-style resources: [app/src/debug/resources]
Bu çıkışı görüntülemek için aşağıdaki adımları uygulayın:
- Araç penceresi çubuğunda Gradle'i tıklayın.
Uygulamam > Görevler > android'e gidin ve sourceSets'i çift tıklayın.
Görevler klasörünü görmek için Gradle'in senkronizasyon sırasında görev listesini oluşturmasına izin vermeniz gerekir. Bunun için, aşağıdaki adımları uygulayın:
- Dosya > Ayarlar > Deneysel'i (macOS'te Android Studio > Ayarlar > Deneysel) tıklayın.
- Gradle senkronizasyonu sırasında Gradle görev listesini derleme seçeneğinin seçimini kaldırın.
- Gradle görevi yürüttükten sonra, çıkışı görüntülemek için Çalıştır penceresi açılır.
Not: Görev çıktısında, uygulamanız için test çalıştırmak amacıyla kullanmak istediğiniz dosyaların kaynak kümelerini (ör. test/
ve androidTest/
test kaynak kümeleri) nasıl düzenleyeceğiniz de gösterilir.
Yeni bir derleme varyantı oluşturduğunuzda Android Studio, kaynak dizinlerini sizin için oluşturmaz ancak size yardımcı olacak birkaç seçenek sunar. Örneğin, "debug" derleme türünüz için yalnızca java/
dizinini oluşturmak isterseniz:
- Proje bölmesini açın ve bölmenin üst kısmındaki menüden Proje görünümünü seçin.
MyProject/app/src/
adresine gidin.src
dizinini sağ tıklayın ve Yeni > Dizin'i seçin.- Gradle Kaynak Kümeleri bölümündeki menüden full/java'yı seçin.
- Enter tuşuna basın.
Android Studio, hata ayıklama derleme türünüz için bir kaynak kümesi dizini oluşturur ve ardından bu dizin içinde java/
dizinini oluşturur. Alternatif olarak, belirli bir derleme varyantı için projenize yeni bir dosya eklediğinizde Android Studio dizinleri sizin için oluşturabilir.
Örneğin, "hata ayıklama" derleme türünüz için bir değerler XML dosyası oluşturmak istiyorsanız:
- Proje bölmesinde
src
dizinini sağ tıklayın ve Yeni > XML > Değer XML Dosyası'nı seçin. - XML dosyasının adını girin veya varsayılan adı kullanın.
- Hedef Kaynak Grubu'nun yanındaki menüden hata ayıklama'yı seçin.
- Son'u tıklayın.
Hedef kaynak grubu olarak "hata ayıklama" derleme türü belirtildiğinden, Android Studio XML dosyasını oluştururken gerekli dizinleri otomatik olarak oluşturur. Elde edilen dizin yapısı Şekil 1'de gösterilmiştir.
Etkin kaynak kümelerinin simgelerinde, etkin olduklarını gösteren yeşil bir gösterge bulunur. debug
kaynak grubunun sonuna [main]
eklenir. Bu, debug
kaynak grubunun main
kaynak grubuyla birleştirileceğini gösterir.
Aynı prosedürü kullanarak src/demo/
gibi ürün varyasyonları ve src/demoDebug/
gibi derleme varyantları için kaynak kümesi dizinleri de oluşturabilirsiniz. Ayrıca, src/androidTestDemoDebug/
gibi belirli derleme varyantlarını hedefleyen test kaynak kümeleri oluşturabilirsiniz. Daha fazla bilgi edinmek için kaynak kümelerini test etme hakkındaki makaleyi okuyun.
Varsayılan kaynak grubu yapılandırmalarını değiştirme
Kaynak kümesi oluşturma ile ilgili önceki bölümde açıklandığı gibi, Gradle'ın beklediği varsayılan kaynak kümesi dosya yapısında düzenlenmemiş kaynaklarınız varsa Gradle'ın bir kaynak kümesinin her bileşeni için dosyaları toplamak üzere aradığı yeri değiştirmek üzere
sourceSets
bloğunu kullanabilirsiniz.
sourceSets
bloğu, android
bloğunda olmalıdır. Kaynak dosyaların yerini değiştirmeniz gerekmez. Gradle'e yalnızca modül düzeyindeki build.gradle.kts
dosyasına göre yolları sağlamanız yeterlidir. Gradle bu dosyada her kaynak kümesi bileşeninin dosyalarını bulabilir. Hangi bileşenleri yapılandırabileceğinizi ve bunları birden fazla dosya veya dizinle eşleyip eşleyemeyeceğinizi öğrenmek için Android Gradle eklentisi API referansı başlıklı makaleyi inceleyin.
Aşağıdaki kod örneği, app/other/
dizinindeki kaynakları main
kaynak setinin belirli bileşenleriyle eşler ve androidTest
kaynak setinin kök dizinini değiştirir:
Kotlin
android { ... // Encapsulates configurations for the main source set. sourceSets.getByName("main") { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.setSrcDirs(listOf("other/java")) // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.setSrcDirs(listOf("other/res1", "other/res2")) // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile("other/AndroidManifest.xml") ... } // Create additional blocks to configure other source sets. sourceSets.getByName("androidTest") { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot("src/tests") ... } } ...
Groovy
android { ... sourceSets { // Encapsulates configurations for the main source set. main { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.srcDirs = ['other/java'] // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.srcDirs = ['other/res1', 'other/res2'] // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile 'other/AndroidManifest.xml' ... } // Create additional blocks to configure other source sets. androidTest { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot 'src/tests' ... } } } ...
Bir kaynak dizininin yalnızca bir kaynak kümesine ait olabileceğini unutmayın. Örneğin, aynı test kaynaklarını hem test
hem de androidTest
kaynak kümeleriyle paylaşamazsınız. Bunun nedeni, Android Studio'nun her kaynak grubu için ayrı IntelliJ modülleri oluşturması ve kaynak grupları arasında yinelenen içerik köklerini destekleyememesidir.
Kaynak kümeleriyle derleme
Yalnızca belirli yapılandırmalarla paketlenmesini istediğiniz kod ve kaynakları içerecek şekilde kaynak kümesi dizinlerini kullanabilirsiniz. Örneğin, "demo" ürün çeşidinin ve "debug" derleme türünün çapraz ürünü olan "demoDebug" derleme varyantını oluşturuyorsanız Gradle bu dizinleri inceler ve aşağıdaki önceliği verir:
-
src/demoDebug/
(derleme varyantı kaynak grubu) -
src/debug/
(derleme türü kaynak grubu) -
src/demo/
(ürün türü kaynak grubu) -
src/main/
(ana kaynak grubu)
Ürün aromalarının kombinasyonları için oluşturulan kaynak kümeleri, tüm aroma boyutlarını içermelidir. Örneğin, derleme varyantı kaynak grubu, derleme türünün ve tüm lezzet boyutlarının birleşimi olmalıdır. Tümünü değil de birden fazla lezzet boyutunu kapsayan klasörler içeren kod ve kaynakların birleştirilmesi desteklenmez.
Birden fazla ürün aromasını birleştirirseniz ürün aromaları arasındaki öncelik, ait oldukları aroma boyutuna göre belirlenir.
android.flavorDimensions
mülkü ile aroma boyutlarını listelediğinizde, listelediğiniz ilk aroma boyutuna ait ürün aromaları, ikinci aroma boyutuna ait olanlardan daha yüksek önceliğe sahiptir. Ayrıca, ürün aroması kombinasyonları için oluşturduğunuz kaynak kümeleri, tek bir ürün aromasına ait kaynak kümelerinden daha yüksek önceliğe sahiptir.
Öncelik sırası, Gradle kod ve kaynakları birleştirirken hangi kaynak grubunun daha yüksek önceliğe sahip olacağını belirler. demoDebug/
kaynak grubu dizini muhtemelen söz konusu derleme varyantına özgü dosyalar içerdiğinden, demoDebug/
'te debug/
'te de tanımlanmış bir dosya varsa Gradle, demoDebug/
kaynak grubundaki dosyayı kullanır. Benzer şekilde Gradle, derleme türündeki dosyalara ve ürün çeşidi kaynak ayarlarına main/
'deki aynı dosyalara göre daha yüksek öncelik verir.
Gradle, aşağıdaki derleme kurallarını uygularken bu öncelik sırasını dikkate alır:
kotlin/
veyajava/
dizinlerindeki tüm kaynak kodları tek bir çıkış oluşturmak için birlikte derlenir.Not: Gradle, belirli bir yapı varyantında aynı Kotlin veya Java sınıfını tanımlayan iki veya daha fazla kaynak kümesi diziniyle karşılaşırsa yapı hatası oluşturur. Örneğin, hata ayıklama uygulaması oluştururken hem
src/debug/Utility.kt
hem desrc/main/Utility.kt
'ü tanımlayamazsınız. Bunun nedeni, Gradle'in derleme işlemi sırasında bu dizinlerin her ikisine de bakması ve "yinelenen sınıf" hatası vermesidir. Farklı derleme türleri içinUtility.kt
'ün farklı sürümlerini istiyorsanız her derleme türü, dosyanın kendi sürümünü tanımlamalı vemain/
kaynak grubuna dahil etmemelidir.- Manifestler tek bir manifestte birleştirilir. Öncelik, önceki örnekteki listeyle aynı sırada verilir. Yani bir derleme türüne ait manifest ayarları, ürün çeşidine ait manifest ayarlarını geçersiz kılar. Daha fazla bilgi edinmek için manifest birleştirme hakkındaki makaleyi inceleyin.
values/
dizinlerindeki dosyalar birleştirilir. İki dosya aynı ada sahipse (ör. ikistrings.xml
dosyası) öncelik, önceki örnekteki listedeki sırayla verilir. Yani, derleme türü kaynak grubundaki bir dosyada tanımlanan değerler, aynı dosyada ürün çeşidinde tanımlanan değerleri geçersiz kılar.res/
veasset/
dizinlerindeki kaynaklar birlikte paketlenir. İki veya daha fazla kaynak grubunda aynı ada sahip kaynaklar tanımlanmışsa öncelik, önceki örnekteki listeyle aynı sırayla verilir.- Gradle, uygulamayı oluştururken kitaplık modülü bağımlılıklarına dahil edilen kaynaklara ve manifest dosyalarına en düşük önceliği verir.
Bağımlılıkları bildirme
Belirli bir derleme varyantı veya test kaynak grubu için bağımlılık yapılandırmak üzere, aşağıdaki örnekte gösterildiği gibi Implementation
anahtar kelimesinden önce derleme varyantının veya test kaynak grubunun adını ekleyin:
Kotlin
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. "freeImplementation"(project(":mylibrary")) // Adds a remote binary dependency only for local tests. testImplementation("junit:junit:4.12") // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1") }
Groovy
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. freeImplementation project(":mylibrary") // Adds a remote binary dependency only for local tests. testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1' }
Bağımlılıkları yapılandırma hakkında daha fazla bilgi için Derleme bağımlılıkları ekleme başlıklı makaleyi inceleyin.
Varyantlara duyarlı bağımlılık yönetimi kullanın
Android Gradle Plugin 3.0.0 ve sonraki sürümler, bir kitaplığı kullanırken varyantları otomatik olarak eşleştiren yeni bir bağımlılık mekanizması içerir. Bu, bir uygulamanın debug
varyantının, bir kitaplığın debug
varyantını otomatik olarak kullandığı anlamına gelir. Bu özellik, farklı sürümler kullanıldığında da çalışır: Bir uygulamanın freeDebug
sürümü, kitaplığın freeDebug
sürümünü tüketir.
Eklentinin varyantları doğru şekilde eşlemesi için doğrudan eşlemenin mümkün olmadığı durumlarda aşağıdaki bölümde açıklandığı şekilde eşleşen yedek seçenekler sağlamanız gerekir.
Örneğin, uygulamanızın "hazırlama" adlı bir derleme türünü yapılandırdığını, ancak kitaplık bağımlılıklarından birinin bunu yapmadığını varsayalım. Eklenti, uygulamanızın "hazırlama" sürümünü oluşturmaya çalışırken hangi kitaplık sürümünün kullanılacağını bilemez ve aşağıdakine benzer bir hata mesajı görürsünüz:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
Varyant eşleştirmeyle ilgili derleme hatalarını çözme
Bu eklenti, Gradle'in bir uygulama ile bağımlılık arasında doğrudan varyant eşleşmesinin mümkün olmadığı durumları nasıl çözdüğünü kontrol etmenize yardımcı olacak DSL öğeleri içerir.
Aşağıda, varyant bilinçli bağımlılık eşleştirmeyle ilgili sorunların ve DSL özelliklerini kullanarak bu sorunları nasıl çözeceğinizin listesi verilmiştir:Uygulamanız, kitaplık bağımlılığının içermediği bir derleme türü içeriyor.
Örneğin, uygulamanız "hazırlama" derleme türünü içeriyor ancak bir bağımlılık yalnızca "hata ayıklama" ve "sürüm" derleme türlerini içeriyor.
Bir kitaplık bağımlılığı, uygulamanızda bulunmayan bir derleme türü içerdiğinde sorun olmadığını unutmayın. Bunun nedeni, eklentinin bağımlılıktan bu derleme türünü hiçbir zaman istememesidir.
Belirli bir derleme türü için alternatif eşleşmeleri belirtmek üzere
matchingFallbacks
simgesini kullanın.Kotlin
// In the app's build.gradle.kts file. android { buildTypes { getByName("debug") {} getByName("release") {} create("staging") { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks += listOf("debug", "qa", "release") } } }
Groovy
// In the app's build.gradle file. android { buildTypes { debug {} release {} staging { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks = ['debug', 'qa', 'release'] } } }
Hem uygulamada hem de kitaplık bağımlılığında bulunan belirli bir tat boyutu için uygulamanız, kitaplıkta bulunmayan tatlar içeriyor.
Örneğin, hem uygulamanız hem de kitaplık bağımlılıklarınızda bir "katman" çeşidi boyutu bulunur. Ancak uygulamadaki "katman" boyutu "ücretsiz" ve "ücretli" varyantları içerirken bağımlılık, aynı boyut için yalnızca "demo" ve "ücretli" varyantlarını içerir.
Hem uygulamada hem de kitaplık bağımlılıklarında bulunan belirli bir lezzet boyutu için, bir kitaplığın uygulamanızda bulunmayan bir ürün lezzetini içermesi durumunda sorun olmadığını unutmayın. Bunun nedeni, eklentinin bu aromayı bağımlılıktan hiçbir zaman istememesidir.
Uygulamanın "ücretsiz" ürün aroması için alternatif eşleşmeleri belirtmek üzere
matchingFallbacks
değerini kullanın.Kotlin
// In the app's build.gradle.kts file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions += "tier" productFlavors { create("paid") { dimension = "tier" // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } create("free") { dimension = "tier" // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks += listOf("demo", "trial") } } }
Groovy
// In the app's build.gradle file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions 'tier' productFlavors { paid { dimension 'tier' // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } free { dimension 'tier' // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks = ['demo', 'trial'] } } }
Kitaplık bağımlılığı, uygulamanızda bulunmayan bir lezzet boyutu içeriyor.
Örneğin, bir kitaplık bağımlılığı "minApi" boyutu için tatlar içeriyor ancak uygulamanız yalnızca "tier" boyutu için tatlar içeriyor. Uygulamanızın "freeDebug" sürümünü derlemek istediğinizde, eklenti bağımlılık için "minApi23Debug" mi yoksa "minApi18Debug" sürümünü mü kullanacağını bilemez.
Uygulamanızda, kitaplık bağımlılığının içermediği bir lezzet boyutu olduğunda sorun olmadığını unutmayın. Bunun nedeni, eklentinin yalnızca bağımlılıkta bulunan boyutların türleriyle eşleşmesidir. Örneğin, bir bağımlılık ABI'ler için bir boyut içermiyorsa uygulamanızın "freeX86Debug" sürümü, bağımlığın "freeDebug" sürümünü kullanır.
Aşağıdaki örnekte gösterildiği gibi, eklentinin her eksik boyuttan seçeceği varsayılan çeşidi belirtmek için
defaultConfig
bloğundamissingDimensionStrategy
kullanın. Ayrıca,productFlavors
bloğundaki seçimlerinizi geçersiz kılabilirsiniz. Böylece her lezzet, eksik bir boyut için farklı bir eşleme stratejisi belirtebilir.Kotlin
// In the app's build.gradle.kts file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy("minApi", "minApi18", "minApi23") // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy("abi", "x86", "arm64") } flavorDimensions += "tier" productFlavors { create("free") { dimension = "tier" // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the "minApi" dimension. missingDimensionStrategy("minApi", "minApi23", "minApi18") } create("paid") {} } }
Groovy
// In the app's build.gradle file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy 'minApi', 'minApi18', 'minApi23' // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy 'abi', 'x86', 'arm64' } flavorDimensions 'tier' productFlavors { free { dimension 'tier' // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the 'minApi' dimension. missingDimensionStrategy 'minApi', 'minApi23', 'minApi18' } paid {} } }
Daha fazla bilgi için Android Gradle eklentisi DSL referansında matchingFallbacks
ve missingDimensionStrategy
bölümlerine bakın.
İmzalama ayarlarını yapılandırma
Gradle, bu derleme için açıkça bir imzalama yapılandırması tanımlamadığınız sürece yayınlama derlemenizin APK'sını veya AAB'sini imzalamaz. Henüz bir imzalama anahtarınız yoksa Android Studio'yu kullanarak bir yükleme anahtarı ve anahtar mağazası oluşturun.
Gradle derleme yapılandırmalarını kullanarak sürüm derleme türünüzün imzalama yapılandırmalarını manuel olarak yapılandırmak için:
- Anahtar deposu oluşturun. Anahtar deposu, bir dizi özel anahtar içeren ikili bir dosyadır. Anahtar deponuzu güvenli bir yerde tutmanız gerekir.
- Özel anahtar oluşturun. Özel anahtar, uygulamanızı dağıtım için imzalamak amacıyla kullanılır ve asla uygulamaya dahil edilmez veya yetkisiz üçüncü taraflara açıklanmaz.
-
İmzalama yapılandırmasını modül düzeyindeki
build.gradle.kts
dosyasına ekleyin:Kotlin
... android { ... defaultConfig {...} signingConfigs { create("release") { storeFile = file("myreleasekey.keystore") storePassword = "password" keyAlias = "MyReleaseKey" keyPassword = "password" } } buildTypes { getByName("release") { ... signingConfig = signingConfigs.getByName("release") } } }
Groovy
... android { ... defaultConfig {...} signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { ... signingConfig signingConfigs.release } } }
Not: Yayın anahtarınızın ve anahtar deponuzun şifrelerini derleme dosyasına dahil etmek iyi bir güvenlik uygulaması değildir. Bunun yerine, derleme dosyasını bu şifreleri ortam değişkenlerinden alacak şekilde yapılandırın veya derleme işleminin bu şifreleri sizden istemesini sağlayın.
Bu şifreleri ortam değişkenlerinden almak için:
Kotlin
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
Groovy
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
Alternatif olarak, anahtar deposunu yerel bir mülk dosyasından da yükleyebilirsiniz. Güvenlik nedeniyle bu dosyayı kaynak denetimine eklemeyin. Bunun yerine, her geliştirici için yerel olarak ayarlayın. Daha fazla bilgi için Derleme dosyalarınızdan imzalama bilgilerini kaldırma başlıklı makaleyi inceleyin.
Bu işlemi tamamladıktan sonra uygulamanızı dağıtabilir ve Google Play'de yayınlayabilirsiniz.
Uyarı: Anahtar deponuzu ve özel anahtarınızı güvenli bir yerde saklayın ve bunların güvenli yedeklerine sahip olduğunuzdan emin olun. Play Uygulama İmzalama'yı kullanıyorsanız ve yükleme anahtarınızı kaybederseniz Play Console'u kullanarak sıfırlama isteğinde bulunabilirsiniz. Play Uygulama İmzalama olmadan uygulama yayınlıyorsanız (Ağustos 2021'den önce oluşturulmuş uygulamalar için) ve uygulama imzalama anahtarınızı kaybederseniz uygulamanızın tüm sürümlerini her zaman aynı anahtarla imzalamanız gerektiğinden uygulamanızda güncelleme yayınlayamazsınız.
Wear OS uygulamalarını imzalama
Wear OS uygulamaları yayınlanırken hem saat APK'sı hem de isteğe bağlı telefon APK'sı aynı anahtarla imzalanmalıdır. Wear OS uygulamalarını paketleme ve imzalama hakkında daha fazla bilgi için Wear uygulamalarını paketleme ve dağıtma başlıklı makaleyi inceleyin.