Birden fazla APK oluşturma

Dikkat: Ağustos 2021'den bu yana yalnızca yeni uygulamalar App Bundle olarak yayınlanmalıdır. Uygulamanızı Google Play'de yayınlarsanız Android App Bundle oluşturup yükleyin. Zaman Google Play aşağıdakiler için optimize edilmiş APK'ları otomatik olarak oluşturur ve sunar: her kullanıcının cihaz yapılandırmasına izin verir, böylece sadece kod ve kaynakları indirirler. en iyi uygulamaları paylaştık. Birden fazla APK yayınlamak istiyorsanız AAB biçimini desteklemeyen bir mağazada yayınlama Böyle bir durumda, her APK'yı kendiniz oluşturmanız, imzalamanız ve yönetmeniz gerekir.

Hedef cihazlarınızın tümünü destekleyecek tek bir APK oluşturmak daha iyi olsa da her mümkün olduğunda, bu işlem, dosyalar nedeniyle çok büyük bir APK birden çok destekleniyor ekran yoğunlukları veya Uygulama İkili Programı Arayüzler (ABI'ler). APK'nızın boyutunu küçültmenin bir yolu da birden fazla APK'ya sahip belirli ekran yoğunluklarına veya ABI'lere ilişkin dosyalar içermelidir.

Gradle yalnızca belirli kod ve kaynakları içeren ayrı APK'lar oluşturabilir ABI'ye otomatik olarak eklenmesini sağlar. Bu sayfada, derlemenizi birden fazla APK oluşturabilirsiniz. Uygulamanızın farklı sürümlerini oluşturmanız gerekiyorsa bunun yerine derleme varyantları kullanın.

Derlemenizi birden fazla APK için yapılandırma

Derlemenizi birden fazla APK için yapılandırmak üzere Modül düzeyinize splits blok build.gradle dosyası. Şuranın içinde: splits blok, sağla Gradle'ın nasıl oluşturmasını istediğinizi belirten bir density bloğu yoğunluk bazında APK'lar veya Gradle'ı nasıl istediğinizi belirten bir abi bloğu oluşturmak için kullanabilirsiniz. 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ına yönelik ayrı APK'lar oluşturmak için density blok içinde splits blok. density blokunuzda bir ve uyumlu ekran boyutlarının listesini inceleyin. Yalnızca uyumlu ekran boyutlarına ihtiyacınız varsa Her bir APK'nın manifest dosyasındaki <compatible-screens> öğeleri.

Aşağıdaki Gradle DSL seçenekleri, ekran yoğunlukları:

Groovy için enable, Kotlin metni için isEnable
. Bu öğeyi true olarak ayarlarsanız Gradle birden fazla APK oluşturur bu ayarları değiştirebilirsiniz. Varsayılan değer: false
exclude
. Gradle'ı istemediğiniz yoğunlukların virgülle ayrılmış listesini belirtir ayrı APK'lar oluşturabilirsiniz. Şu durumlarda exclude kullanın: Çoğu yoğunluk için APK oluşturmak istiyorsunuz ancak birkaç tane hariç tutmalısınız uygulamanızın desteklemediği yoğunluklara gidin.
reset()

Varsayılan ekran yoğunlukları listesini temizler. Yalnızca İstediğiniz yoğunlukları belirten include öğesi ekle.

Aşağıdaki snippet, yoğunluk listesini yalnızca reset() numaralı telefonu arayarak ldpi ve xxhdpi tuşuna basarak listeyi temizleyin ve include komutunu kullanın:

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 oluşturmasını istediğiniz yoğunlukların virgülle ayrılmış listesini belirtir APK'lar. Yalnızca reset() ile birlikte kullanarak tam yoğunluk listesi.
compatibleScreens

Uyumlu ekran boyutlarının virgülle ayrılmış listesini belirtir. Bu eşleşen bir için manifest dosyasındaki <compatible-screens> düğümünü inceleyin her APK'yı kullanın.

Bu ayar, her iki ekranı da kolayca yönetmenizi sağlar. yoğunlukları ve ekran boyutları gibi öğeleri aynı build.gradle bölümünde bulabilirsiniz. Ancak, <compatible-screens>, cihaz türlerini sınırlandırabilir en iyi uygulamaları paylaşacağız. Farklı destek yöntemlerini daha fazla bilgi için ekran uyumluluğuna genel bakış başlıklı makaleyi inceleyin.

Çünkü ekran yoğunluğuna dayalı her APK Belirli kısıtlamalara sahip <compatible-screens> etiketi APK'nın hangi ekran türlerini desteklediğiyle ilgili (birkaç tane ekran görüntüsü yayınlasanız bile) APK'lar: Bazı yeni cihazlar birden fazla APK filtrenizle eşleşmez. Dolayısıyla, Gradle her zaman öğe içeren ek bir evrensel APK oluşturur tüm ekran yoğunlukları için uygundur ve <compatible-screens> etiketi. Bunu yayınla farklı yoğunluklardaki APK'larınızla birlikte evrensel APK'yı APK'ları <compatible-screens> etiketi.

Aşağıdaki örnek, her bir kullanıcı için ayrı bir APK ekran yoğunluk (ldpi, xxhdpi ve hariç) xxxhdpi. Bu işlem, içeriği kaldırmak için exclude kullanılarak yapılır bu üç yoğunluğu, varsayılan tüm yoğunluk listesinden çıkarır.

Eski

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")
        }
    }
}

Farklı derlemeleri özelleştirme hakkında daha fazla bilgi uygulamanızın belirli ekran türlerine ve cihazlara yönelik sürümlerini, Kısıtlanmış olarak bildir ekran desteğine başvurun.

ABI'ler için birden fazla APK yapılandırın

Farklı ABI'ler için ayrı APK'lar oluşturmak üzere bir abi bloğu ekleyin splits blok. abi blokunuzda şunları içeren bir liste sağlayın: tıklayın.

Aşağıdaki Gradle DSL seçenekleri, ABI:

Groovy için enable veya Kotlin komut dosyası için isEnable
Bu öğeyi true olarak ayarlarsanız Gradle birden fazla öğe oluşturur Tanımladığınız ABI'lere dayalı APK'lar. Varsayılan değer false değeridir.
exclude
. Gradle'ın yapmasını istemediğiniz ABI'lerin virgülle ayrılmış listesini belirtir ayrı APK'lar oluşturabilirsiniz. Oluşturmak istiyorsanız exclude kullanın Çoğu ABI için APK'lar; ancak uygulamanızın sunmadığı birkaç ABI'yi hariç tutması gerekir destek.
reset()

Varsayılan ABI listesini temizler. Yalnızca Eklemek istediğiniz ABI'leri belirtmek için include öğesi.

Aşağıdaki snippet, ABI'lerin listesini yalnızca x86 ve Listeyi temizlemek için reset() numaralı telefonu arayarak x86_64 ve include kullanarak:

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 . Kesin bir değer belirtmek için yalnızca reset() ile birlikte kullanın ABI listesidir.
Groovy için universalApk veya Groovy için isUniversalApk Kotlin alfabesi

true durumunda Gradle, ABI APK'larına özeldir. Evrensel APK, bir tek APK. Varsayılan değer false değeridir.

Bu seçeneğin yalnızca splits.abi blokunda mevcut. Birden fazla APK oluştururken Gradle her zaman şunları içeren evrensel bir APK üretir: tüm ekran yoğunluklarına yönelik kod ve kaynakları içerir.

Aşağıdaki örnek her ABI için ayrı bir APK oluşturur: x86 ve x86_64. Bu işlem, reset() kullanılarak yapılır boş bir ABI listesiyle başlayın, ardından bir ABI'nin bulunduğu include Her biri bir APK alan ABI'lerin listesi.

Eski

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 bkz. Destekleniyor ABI'ler.

Yerel/C++ kodu olmayan projeler

Yerel/C++ kodu olmayan projeler için Varyant Oluşturma panelinde iki öğe bulunur. sütunlar: Modül ve Etkin Derleme Varyant, Şekil 1'de gösterildiği gibidir.


Derleme varyantları paneli Şekil 1. Varyant Oluştur panelinde, aşağıdaki gibi olmayan projeler için iki sütun bulunur: yerel/C++ kodu.

Şu öğe için Etkin Derleme Varyantı değeri: modülü, 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 projeler için Varyant Oluşturma panelinde üç öğe bulunur. sütunlar: Modül, Etkin Derleme Varyant ve Etkin ABI (Şekil 2'de gösterildiği gibi).

. Şekil 2. Varyant Derleme paneli, dönüşüm izleme için Etkin ABI sütununu ekler. yerel/C++ kodu içeren projeler için geçerlidir.

Modülün Aktif Derleme Varyantı değeri Dağıtılan ve düzenleyicide görünen derleme varyantını belirler. Yerel modüllerde Active ABI değeri, düzenleyicinin ancak dağıtımları etkilemez.

Derleme türünü veya ABI'yı değiştirmek için:

  1. Etkin Derleme Varyantı hücresini tıklayın veya Etkin ABI sütununu seçin.
  2. Listeden istediğiniz varyantı veya ABI'yi seçin girin. Otomatik olarak yeni bir senkronizasyon çalıştırılır.

Bir uygulama veya kitaplık modülü için iki sütundan birinin değiştirilmesi, değişikliği tüm bağımlı satırlar.

Sürüm oluşturmayı yapılandırma

Gradle birden fazla APK oluşturduğunda varsayılan olarak her APK modül düzeyinde belirtilen sürüm bilgileri build.gradle veya build.gradle.kts dosyası. Çünkü Google Play Store, aynı uygulama için tümünde birden fazla APK'ya sahip olan birden fazla APK'ya izin aynı sürüm bilgilerine sahipse her APK'nın benzersiz bir sürüm versionCode önce Play Store'a yükleyin.

Modül düzeyindeki build.gradle dosyanızı şu şekilde yapılandırabilirsiniz: Her bir APK için versionCode değerini geçersiz kılın. Eşleme oluşturarak her ABI ve yapılandırdığınız yoğunluk için benzersiz bir sayısal değer atar için birden fazla APK kullanıyorsanız çıkış sürüm kodunu defaultConfig veya sayısal değerin atanmış olduğu productFlavors bloğu ABI'yı seçin.

Aşağıdaki örnekte, x86 ABI için APK 2004'ün versionCode ve x86_64 ABI'sını alır 3004 üzerinden versionCode alıyor.

Sürüm kodlarını 1000 gibi büyük artışlarla atamak, uygulamanızı güncellemeniz gerekirse benzersiz sürüm kodları atamanıza olanak tanır. Örneğin, Örneğin, defaultConfig.versionCode Gradle bir versionCode 2005 x86 APK'sını ve 3005'i x86_64 APK'sına.

İpucu: Derlemeniz evrensel APK içeriyorsa buna versionCode daha düşük bir fiyat sunuyor. Çünkü Google Play Store, uygulamanızın hem kendi hedef cihazla uyumludur ve en büyük versionCode;versionCode evrensel APK, Google Play Store'un APK'lara öncelik vermeyi unutmayın. Aşağıdaki örnek kod bunu evrensel APK'nın Varsayılan versionCode.

Eski

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

Birden fazla APK oluşturma

Modül düzeyindeki build.gradle öğenizi yapılandırdıktan sonra veya Birden fazla APK oluşturmak için build.gradle.kts dosyasını tıklayın, Oluştur > Şu anki tüm APK'ları derlemek için APK'yı oluşturun Proje bölmesindeki seçili modülü seçin. Gradle, APK'ları oluşturur projenin build/outputs/apk/ içinde her yoğunluk veya ABI için dizin.

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 bir APK oluşturur her yoğunluk ve ABI kombinasyonunda gösterilir.

Örneğin, build.gradle snippet'i, mdpi ve hdpi yoğunluk ve ayrıca x86 ve x86_64 ABI'leri:

Eski

...
  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ırmadaki çıkış aşağıdaki 4 APK'yı içerir:

  • app-hdpiX86-release.apk: Şunun için kod ve kaynakları içerir: hdpi yoğunluk ve x86 ABI.
  • app-hdpiX86_64-release.apk: Şunun için kod ve kaynakları içerir: hdpi yoğunluk ve x86_64 ABI.
  • app-mdpiX86-release.apk: Şunun için kod ve kaynakları içerir: mdpi yoğunluk ve x86 ABI.
  • app-mdpiX86_64-release.apk: Şunun için kod ve kaynakları içerir: mdpi yoğunluk ve x86_64 ABI.

Ekran yoğunluğuna göre birden fazla APK oluştururken Gradle her zaman tüm yoğunluklara yönelik kod ve kaynakları içeren evrensel bir APK oluşturur, ek olarak yoğunluğa göre APK'ları da içerir.

Temelinde birden fazla APK oluştururken Gradle, yalnızca tüm uygulamalar için kod ve kaynak içeren bir APK ABI'ler, universalApk true öğesini build.gradle dosyanızda splits.abi blok (Groovy için) veya isUniversalApk = true build.gradle.kts dosyanızda splits.abi blok (Kotlin komut dosyası için).

APK dosya adı biçimi

Gradle, birden fazla APK oluştururken APK dosya adlarını aşağıdakileri kullanarak oluşturur: şema:

modulename-screendensityABI-buildvariant.apk

Şema bileşenleri şunlardır:

modulename
. Derlenmekte olan modül adını belirtir.
screendensity
. Ekran yoğunluğu için birden fazla APK etkinse ekranı belirtir yoğunluğu (örneğin, mdpi).
ABI

ABI için birden fazla APK etkinleştirilirse APK için ABI'yi belirtir. Örneğin, x86 olarak.

Hem ekran yoğunluğu hem de ABI için birden fazla APK etkinleştirilirse Gradle, yoğunluk adını ABI adıyla birleştirir. Örneğin, mdpiX86 universalApk, ABI için etkinleştirildiyse APK'lar, Gradle, evrensel APK'nın ABI kısmı olarak universal değerini kullanır dosya adı.

buildvariant
. Derlenmekte olan derleme varyantını (ör. debug) belirtir.

Örneğin, mdpi myApp hata ayıklama sürümünde, APK dosya adı myApp-mdpi-debug.apk. Lansman hem Android hem de iOS için birden fazla APK oluşturacak şekilde mdpi ekran yoğunluğu ve x86 ABI'nın APK dosya adı şu şekildedir: myApp-mdpiX86-release.apk.