Dikkat: Ağustos 2021'den itibaren tüm yeni uygulamalar App Bundle olarak yayınlanmalıdır. Uygulamanızı Google Play'de yayınlarsanız Android App Bundle oluşturup yükleyin. Bunu yaptığınızda Google Play, her kullanıcının cihaz yapılandırması için optimize edilmiş APK'ları otomatik olarak oluşturur ve sunar. Böylece kullanıcılar yalnızca uygulamanızı çalıştırmak için ihtiyaç duydukları kodu ve kaynakları indirir. AAB biçimini desteklemeyen bir mağazada yayınlıyorsanız birden fazla APK yayınlamak faydalı olur. Bu durumda, her APK'yı kendiniz oluşturmanız, imzalamanız ve yönetmeniz gerekir.
Mümkün olduğunda tüm hedef cihazlarınızı desteklemek için tek bir APK oluşturmak daha iyi olsa da birden fazla ekran yoğunluğunu veya uygulama ikili arayüzünü (ABI) destekleyen dosyalar nedeniyle çok büyük bir APK oluşturabilirsiniz. APK'nızın boyutunu düşürmenin bir yolu, belirli ekran yoğunluklarına veya ABI'lere ait dosyalar içeren birden fazla APK oluşturmaktır.
Gradle, her yoğunluk veya ABI'ye özel kod ve kaynaklar içeren ayrı APK'lar oluşturabilir. Bu sayfada, birden fazla APK oluşturmak için derlemenizi nasıl yapılandıracağınız açıklanmaktadır. Uygulamanızın ekran yoğunluğuna veya ABI'ye bağlı olmayan farklı sürümlerini oluşturmanız gerekiyorsa bunun yerine derleme varyantlarını kullanın.
Derlemenizi birden fazla APK için yapılandırma
Derlemenizi birden fazla APK için yapılandırmak amacıyla modül düzeyindeki build.gradle
dosyanıza bir
splits
bloğu ekleyin. splits
bloğunda, Gradle'in yoğunluk başına APK'ları nasıl oluşturmasını istediğinizi belirten bir density
bloğu veya Gradle'in ABI başına APK'ları nasıl oluşturmasını istediğinizi belirten bir abi
bloğu sağlayın. Hem yoğunluk hem de ABI blokları sağlayabilirsiniz. Derleme sistemi, her yoğunluk ve ABI kombinasyonu için bir APK oluşturur.
Ekran yoğunlukları için birden fazla APK yapılandırma
Farklı ekran yoğunlukları için ayrı APK'lar oluşturmak isterseniz splits
bloğunuzun içine bir density
bloğu ekleyin. density
bloğunuzda, istenen ekran yoğunluklarının ve uyumlu ekran boyutlarının listesini sağlayın. Uyumlu ekran boyutları listesini yalnızca her APK'nın manifest dosyasında belirli
<compatible-screens>
öğelerine ihtiyacınız varsa kullanın.
Aşağıdaki Gradle DSL seçenekleri, ekran yoğunlukları için birden fazla APK yapılandırmak amacıyla kullanılır:
-
Groovy için
enable
, Kotlin komut dosyası içinisEnable
-
Bu öğeyi
true
olarak ayarlarsanız Gradle, tanımladığınız ekran yoğunluklarına göre birden fazla APK oluşturur. Varsayılan değer:false
. -
exclude
-
Gradle'ın ayrı APK'lar oluşturmasını istemediğiniz yoğunlukların virgülle ayrılmış listesini belirtir. Çoğu yoğunluk için APK oluşturmak ancak uygulamanızın desteklemediği birkaç yoğunluğu hariç tutmak istiyorsanız
exclude
seçeneğini kullanın. -
reset()
-
Varsayılan ekran yoğunlukları listesini temizler. Yalnızca eklemek istediğiniz yoğunlukları belirtmek için
include
öğesiyle birlikte kullanıldığındaAşağıdaki snippet, listeyi temizlemek için
reset()
'yi çağırıp ardındaninclude
'ı kullanarak yoğunluk listesini yalnızcaldpi
vexxhdpi
olarak ayarlar:reset() // Clears the default list from all densities // to no densities. include "ldpi", "xxhdpi" // Specifies the two densities to generate APKs // for.
-
include
-
Gradle'ın APK oluşturmasını istediğiniz yoğunlukların virgülle ayrılmış listesini belirtir. Yalnızca kesin bir yoğunluk listesi belirtmek için
reset()
ile birlikte kullanın. -
compatibleScreens
-
Uyumlu ekran boyutlarının virgülle ayrılmış listesini belirtir. Bu işlem, her APK'nın manifest dosyasına eşleşen bir
<compatible-screens>
düğümü ekler.Bu ayar, hem ekran yoğunluklarını hem de ekran boyutlarını aynı
build.gradle
bölümünde yönetmenin uygun bir yolunu sunar. Ancak<compatible-screens>
kullanmanız, uygulamanızın çalıştığı cihaz türlerini sınırlayabilir. Farklı ekran boyutlarını desteklemenin alternatif yolları için ekran uyumluluğuna genel bakış başlıklı makaleyi inceleyin.
Ekran yoğunluğuna dayalı her APK, APK'nın desteklediği ekran türleriyle ilgili belirli kısıtlamalar içeren bir <compatible-screens>
etiketi içerir. Bu nedenle, birkaç APK yayınlasanız bile bazı yeni cihazlar birden fazla APK filtrenizle eşleşmez. Bu nedenle, Gradle her zaman tüm ekran yoğunluklarına yönelik öğeler içeren ve <compatible-screens>
etiketi içermeyen ek bir evrensel APK oluşturur. <compatible-screens>
etiketi içeren APK'larla eşleşmeyen cihazlar için yedek bir seçenek sunmak amacıyla bu evrensel APK'yı yoğunluk başına APK'larınızla birlikte yayınlayın.
Aşağıdaki örnekte ldpi
, xxhdpi
ve xxxhdpi
dışındaki her ekran yoğunluğu için ayrı bir APK oluşturulur. Bu işlem, bu üç yoğunluğu tüm yoğunlukların varsayılan listesinden kaldırmak için exclude
kullanılarak yapılır.
Groovy
android { ... splits { // Configures multiple APKs based on screen density. density { // Configures multiple APKs based on screen density. enable true // Specifies a list of screen densities you don't want Gradle to create multiple APKs for. exclude "ldpi", "xxhdpi", "xxxhdpi" // Specifies a list of compatible screen size settings for the manifest. compatibleScreens 'small', 'normal', 'large', 'xlarge' } } }
Kotlin
android { ... splits { // Configures multiple APKs based on screen density. density { // Configures multiple APKs based on screen density. isEnable = true // Specifies a list of screen densities you don't want Gradle to create multiple APKs for. exclude("ldpi", "xxhdpi", "xxxhdpi") // Specifies a list of compatible screen size settings for the manifest. compatibleScreens("small", "normal", "large", "xlarge") } } }
Uygulamanızın farklı derleme varyantlarını belirli ekran türlerine ve cihazlara göre özelleştirme hakkında daha fazla bilgi için Kısıtlanmış ekran desteğini belirtme başlıklı makaleyi inceleyin.
ABI'lar için birden fazla APK yapılandırma
Farklı ABI'ler için ayrı APK'lar oluşturmak amacıyla splits
bloğunuzun içine bir abi
bloğu ekleyin. abi
bloğunuzda, istenen ABI'lerin listesini sağlayın.
ABI başına birden fazla APK yapılandırmak için aşağıdaki Gradle DSL seçenekleri kullanılır:
-
Groovy için
enable
veya Kotlin komut dosyası içinisEnable
- Bu öğeyi
true
olarak ayarlarsanız Gradle, tanımladığınız ABI'lere göre birden fazla APK oluşturur. Varsayılan değer:false
. -
exclude
-
Gradle'ın ayrı APK'lar oluşturmasını istemediğiniz ABI'lerin virgülle ayrılmış listesini belirtir. Çoğu ABI için APK oluşturmak ancak uygulamanızın desteklemediği birkaç ABI'yi hariç tutmak istiyorsanız
exclude
seçeneğini kullanın. -
reset()
-
Varsayılan ABI listesini temizler. Yalnızca eklemek istediğiniz ABI'leri belirtmek için
include
öğesiyle birlikte kullanıldığındaAşağıdaki snippet, listeyi temizlemek için
reset()
'yi çağırıp ardındaninclude
'ı kullanarak ABI listesini yalnızcax86
vex86_64
olarak ayarlar:reset() // Clears the default list from all ABIs to no ABIs. include "x86", "x86_64" // Specifies the two ABIs we want to generate APKs for.
-
include
-
Gradle'ın APK oluşturmasını istediğiniz ABI'lerin virgülle ayrılmış listesini belirtir. Yalnızca ABI'lerin tam listesini belirtmek için
reset()
ile birlikte kullanın. -
Groovy için
universalApk
veya Kotlin komut dosyası içinisUniversalApk
-
true
ise Gradle, ABI başına APK'lara ek olarak evrensel bir APK oluşturur. Evrensel APK, tek bir APK'da tüm ABI'ler için kod ve kaynaklar içerir. Varsayılan değer:false
.Bu seçeneğin yalnızca
splits.abi
bloğunda kullanılabileceğini unutmayın. Gradle, ekran yoğunluğuna göre birden fazla APK oluştururken her zaman tüm ekran yoğunluklarına ait kod ve kaynakları içeren evrensel bir APK oluşturur.
Aşağıdaki örnekte, her ABI için ayrı bir APK oluşturulur: x86
ve x86_64
. Bu işlem, boş bir ABI listesi ile başlamak için reset()
ve ardından her biri bir APK alan ABI'lerin listesi ile include
kullanılarak yapılır.
Groovy
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. enable true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include "x86", "x86_64" // Specifies that you don't want to also generate a universal APK that includes all ABIs. universalApk false } } }
Kotlin
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. isEnable = true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include("x86", "x86_64") // Specifies that you don't want to also generate a universal APK that includes all ABIs. isUniversalApk = false } } }
Desteklenen ABI'lerin listesi için Desteklenen ABI'ler başlıklı makaleyi inceleyin.
Yerel/C++ kodu içermeyen projeler
Yerel/C++ kodu olmayan projelerde Derleme Varyantları panelinde iki sütun bulunur: Modül ve Etkin Derleme Varyantı (Şekil 1'de gösterilmiştir).
Şekil 1. Varyant Oluştur panelinde, yerel/C++ kodu olmayan projeler için iki sütun bulunur.
Modülün Etkin Derleme Varyantı değeri, dağıtılan ve düzenleyicide görünen derleme varyantını belirler. Varyantlar arasında geçiş yapmak için bir modülün Etkin Derleme Varyantı hücresini tıklayın ve liste alanından istediğiniz varyantı seçin.
Yerel/C++ kodu içeren projeler
Yerel/C++ kodu içeren projelerde Derleme Varyantları panelinde üç sütun bulunur: Modül, Etkin Derleme Varyantı ve Etkin ABI (Şekil 2'de gösterilmiştir).
Şekil 2. Derleme Varyantları panelinde, yerel/C++ kodu içeren projeler için Etkin ABI sütunu eklenir.
Modülün Etkin Derleme Varyantı değeri, dağıtılan ve düzenleyicide görünen derleme varyantını belirler. Yerel modüller için Etkin ABI değeri, düzenleyicinin kullandığı ABI'yi belirler ancak dağıtılan öğeleri etkilemez.
Derleme türünü veya ABI'yi değiştirmek için:
- Etkin Derleme Varyantı veya Etkin ABI sütununun hücresini tıklayın.
- Liste alanından istediğiniz varyantı veya ABI'yi seçin. Yeni bir senkronizasyon otomatik olarak çalışır.
Bir uygulama veya kitaplık modülündeki sütunlardan herhangi biri değiştirildiğinde, değişiklik tüm bağımlı satırlara uygulanır.
Sürüm oluşturmayı yapılandırma
Varsayılan olarak Gradle birden fazla APK oluşturduğunda her APK, modül düzeyindeki build.gradle
veya build.gradle.kts
dosyasında belirtilen sürüm bilgilerine sahiptir. Google Play Store, aynı uygulama için aynı sürüm bilgilerine sahip birden fazla APK'ya izin vermez. Bu nedenle, Play Store'a yüklemeden önce her APK'nın benzersiz bir
versionCode
değerine sahip olduğundan emin olmanız gerekir.
Modül düzeyindeki build.gradle
dosyanızı, her APK için versionCode
değerini geçersiz kılacak şekilde yapılandırabilirsiniz. Birden fazla APK'yı yapılandırdığınız her ABI ve yoğunluk için benzersiz bir sayısal değer atayacak bir eşleme oluşturarak çıkış sürüm kodunu, defaultConfig
veya productFlavors
bloğunda tanımlanan sürüm kodunu yoğunluk veya ABI'ye atanan sayısal değerle birleştiren bir değerle geçersiz kılabilirsiniz.
Aşağıdaki örnekte, x86
ABI'nin APK'sı 2004 değerinde bir versionCode
alır ve x86_64
ABI'nin APK'sı 3004 değerinde bir versionCode
alır.
Sürüm kodlarını 1.000 gibi büyük artışlarla atama, uygulamanızı güncellemeniz gerektiğinde daha sonra benzersiz sürüm kodları atamanıza olanak tanır. Örneğin, defaultConfig.versionCode
sonraki bir güncellemede 5'e ulaşırsa Gradle, x86
APK'sına 2005 ve x86_64
APK'sına 3005 versionCode
atar.
İpucu: Derlemeniz evrensel bir APK içeriyorsa bu APK'ya diğer APK'larınızdan daha düşük bir versionCode
atayın.
Google Play Store, uygulamanızın hem hedef cihazla uyumlu hem de en yüksek versionCode
değerine sahip olan sürümünü yükler. Bu nedenle, evrensel APK'ya daha düşük bir versionCode
atamak, Google Play Store'un evrensel APK'ya geçmeden önce APK'larınızdan birini yüklemeye çalışmasını sağlar. Aşağıdaki örnek kod, evrensel APK'nın varsayılan versionCode
değerini geçersiz kılmayarak bu sorunu giderir.
Groovy
android { ... defaultConfig { ... versionCode 4 } splits { ... } } // Map for the version code that gives each ABI a value. ext.abiCodes = ['armeabi-v7a':1, x86:2, x86_64:3] // For per-density APKs, create a similar map: // ext.densityCodes = ['mdpi': 1, 'hdpi': 2, 'xhdpi': 3] import com.android.build.OutputFile // For each APK output variant, override versionCode with a combination of // ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. android.applicationVariants.all { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.each { output -> // Stores the value of ext.abiCodes that is associated with the ABI for this variant. def baseAbiVersionCode = // Determines the ABI for this variant and returns the mapped value. project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiVersionCode != null) { // Assigns the new version code to versionCodeOverride, which changes the // version code for only the output APK, not for the variant itself. Skipping // this step causes Gradle to use the value of variant.versionCode for the APK. output.versionCodeOverride = baseAbiVersionCode * 1000 + variant.versionCode } } }
Kotlin
android { ... defaultConfig { ... versionCode = 4 } splits { ... } } // Map for the version code that gives each ABI a value. val abiCodes = mapOf("armeabi-v7a" to 1, "x86" to 2, "x86_64" to 3) // For per-density APKs, create a similar map: // val densityCodes = mapOf("mdpi" to 1, "hdpi" to 2, "xhdpi" to 3) import com.android.build.api.variant.FilterConfiguration.FilterType.* // For each APK output variant, override versionCode with a combination of // abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. androidComponents { onVariants { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.forEach { output -> val name = output.filters.find { it.filterType == ABI }?.identifier // Stores the value of abiCodes that is associated with the ABI for this variant. val baseAbiCode = abiCodes[name] // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiCode != null) { // Assigns the new version code to output.versionCode, which changes the version code // for only the output APK, not for the variant itself. output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0)) } } } }
Alternatif sürüm kodu şemalarıyla ilgili daha fazla örnek için Sürüm kodları atama başlıklı makaleyi inceleyin.
Birden fazla APK oluşturma
Modül düzeyindeki build.gradle
veya build.gradle.kts
dosyanızı birden fazla APK oluşturacak şekilde yapılandırdıktan sonra, Proje bölmesinde seçili modülün tüm APK'larını oluşturmak için Derle > APK Derle'yi tıklayın. Gradle, projenin build/outputs/apk/
dizininde her yoğunluk veya ABI için APK'ları oluşturur.
Gradle, birden fazla APK yapılandırdığınız her yoğunluk veya ABI için bir APK oluşturur. Hem yoğunluklar hem de ABI'ler için birden fazla APK etkinleştirirseniz Gradle her yoğunluk ve ABI kombinasyonu için bir APK oluşturur.
Örneğin, aşağıdaki build.gradle
snippet'i mdpi
ve hdpi
yoğunlukları ile x86
ve x86_64
ABI'leri için birden fazla APK oluşturmayı sağlar:
Groovy
... splits { density { enable true reset() include "mdpi", "hdpi" } abi { enable true reset() include "x86", "x86_64" } }
Kotlin
... splits { density { isEnable = true reset() include("mdpi", "hdpi") } abi { isEnable = true reset() include("x86", "x86_64") } }
Örnek yapılandırmadan elde edilen çıkış, aşağıdaki 4 APK'yı içerir:
app-hdpiX86-release.apk
:hdpi
yoğunluğu vex86
ABI için kod ve kaynakları içerir.app-hdpiX86_64-release.apk
:hdpi
yoğunluğu vex86_64
ABI için kod ve kaynakları içerir.app-mdpiX86-release.apk
:mdpi
yoğunluğu vex86
ABI için kod ve kaynakları içerir.app-mdpiX86_64-release.apk
:mdpi
yoğunluğu vex86_64
ABI için kod ve kaynakları içerir.
Gradle, ekran yoğunluğuna göre birden fazla APK oluştururken her zaman yoğunluk başına APK'lara ek olarak tüm yoğunluklar için kod ve kaynaklar içeren evrensel bir APK oluşturur.
Gradle, ABI'ye göre birden fazla APK oluştururken build.gradle
dosyanızdaki splits.abi
bloğunda universalApk true
(Groovy için) veya build.gradle.kts
dosyanızdaki splits.abi
bloğunda isUniversalApk = true
(Kotlin komut dosyası için) belirtirseniz yalnızca tüm ABI'ler için kod ve kaynaklar içeren bir APK oluşturur.
APK dosya adı biçimi
Gradle, birden fazla APK derlerken aşağıdaki şemayı kullanarak APK dosya adlarını oluşturur:
modulename-screendensityABI-buildvariant.apk
Şema bileşenleri şunlardır:
-
modulename
- Derlenen modül adını belirtir.
-
screendensity
-
Ekran yoğunluğu için birden fazla APK etkinse APK'nın ekran yoğunluğunu (ör.
mdpi
) belirtir. -
ABI
-
ABI için birden fazla APK etkinleştirildiyse APK'nın ABI'sini (ör.
x86
) belirtir.Hem ekran yoğunluğu hem de ABI için birden fazla APK etkinse Gradle, yoğunluk adını ABI adıyla birleştirir (ör.
mdpiX86
). ABI başına APK'lar içinuniversalApk
etkinleştirilirse Gradle, evrensel APK dosya adının ABI bölümü olarakuniversal
'ı kullanır. -
buildvariant
-
Oluşturulan derleme varyantını (ör.
debug
) belirtir.
Örneğin, uygulamamın hata ayıklama sürümü için mdpi
ekran yoğunluğu APK'sı oluşturulurken APK dosya adı myApp-mdpi-debug.apk
olur. Hem mdpi
ekran yoğunluğu hem de x86
ABI için birden fazla APK oluşturacak şekilde yapılandırılmış myApp uygulama sürümünün APK dosya adı myApp-mdpiX86-release.apk
.