Uwaga: od sierpnia 2021 r. aplikacje muszą być opublikowane jako pakiety aplikacji. Jeśli opublikujesz aplikację w Google Play, utwórz i prześlij pakiet Android App Bundle. Kiedy to Google Play automatycznie generuje i udostępnia zoptymalizowane pliki APK konfiguracji urządzeń poszczególnych użytkowników. Pobierają oni tylko kod i zasoby do uruchomienia aplikacji. Publikowanie wielu plików APK przydaje się, jeśli: w sklepie, który nie obsługuje formatu pakietu AAB. W takim przypadku musisz samodzielnie utworzyć i podpisać każdy plik APK oraz nim zarządzać.
Lepiej jednak utworzyć jeden plik APK do obsługi wszystkich urządzeń docelowych. (w miarę możliwości może to spowodować utworzenie bardzo dużego pakietu APK z powodu plików obsługa wielu elementów gęstości ekranu lub Plik binarny aplikacji Interfejsy (ABI). Jednym ze sposobów zmniejszenia rozmiaru pliku APK jest utworzenie wiele plików APK, zawierają pliki o określonej gęstości ekranu lub interfejsów ABI.
Gradle może tworzyć oddzielne pliki APK zawierające tylko kod i określone zasoby do poszczególnych gęstości i interfejsu ABI. Na tej stronie dowiesz się, jak skonfigurować kompilację wiele plików APK. Jeśli chcesz utworzyć różne wersje aplikacji które nie są oparte na gęstości ekranu lub interfejsu ABI, zamiast tego użyj utwórz warianty.
Konfigurowanie kompilacji dla wielu plików APK
Aby skonfigurować kompilację pod kątem wielu plików APK, dodaj atrybut
splits
na poziomie modułu
build.gradle
. W ciągu
Blokada splits
, podaj
blok density
, który określa sposób generowania przez Gradle
pliki APK według gęstości lub blok abi
, który określa sposób obsługi Gradle
aby generować pliki APK
w formacie ABI. Można podać zarówno gęstość, jak i bloki ABI,
system kompilacji tworzy plik APK dla każdej kombinacji gęstości i interfejsu ABI.
Konfigurowanie wielu plików APK pod kątem gęstości ekranu
Aby utworzyć osobne pliki APK dla różnych gęstości ekranu, dodaj atrybut
Blok density
w Twojej
Blokada: splits
. W bloku density
podaj
listę pożądanej gęstości i zgodnych rozmiarów ekranu. Korzystaj tylko z listy
określonych rozmiarów ekranu.
<compatible-screens>
w pliku manifestu każdego pakietu APK.
Poniższe opcje DSL Gradle służą do konfigurowania wielu plików APK dla gęstości ekranu:
-
enable
– Groovy,isEnable
– skrypt Kotlin -
Jeśli ustawisz ten element na wartość
true
, Gradle wygeneruje wiele plików APK. zgodnie z określonymi gęstościami ekranu. Wartość domyślna tofalse
-
exclude
-
Określa rozdzieloną przecinkami listę gęstości, których Gradle nie ma być obsługiwana
aby wygenerować osobne pliki APK. Użyj
exclude
, jeśli: chcą generować pliki APK dla większości gęstości, ale muszą wykluczyć kilka gęstości, których Twoja aplikacja nie obsługuje. -
reset()
-
Czyści domyślną listę gęstości ekranu. Używaj tylko w połączeniu z
include
, aby określić preferowane gęstości dodaj.Ten fragment kodu ustawia listę gęstości na
ldpi
ixxhdpi
, dzwoniąc pod numerreset()
aby wyczyścić listę, a następnie użyćinclude
:reset() // Clears the default list from all densities // to no densities. include "ldpi", "xxhdpi" // Specifies the two densities to generate APKs // for.
-
include
-
Określa rozdzielaną przecinkami listę gęstości, które ma generować Gradle
Pliki APK dla. Używaj tylko w połączeniu z właściwością
reset()
, aby określić dokładną listę gęstości. -
compatibleScreens
-
Określa rozdzielaną przecinkami listę zgodnych rozmiarów ekranu. Powoduje to wstrzyknięcie kodu pasujące
<compatible-screens>
węzeł w pliku manifestu instancji każdego pliku APK.To ustawienie zapewnia wygodny sposób zarządzania oboma ekranami gęstości i rozmiarów ekranu w tej samej sekcji
build.gradle
. Korzystając jednak z metody<compatible-screens>
może ograniczać typy urządzeń z Twoją aplikacją. Alternatywne sposoby obsługi różnych rozmiarów ekranu, zapoznaj się z przeglądzie zgodności ekranów.
Każdy plik APK oparty na gęstości ekranu zawiera
<compatible-screens>
tag z konkretnymi ograniczeniami
o typach ekranów obsługiwanych przez plik APK – nawet jeśli publikujesz
pliki APK – niektóre nowe urządzenia nie pasują do wielu filtrów plików APK. W związku z tym:
Gradle zawsze generuje dodatkowy uniwersalny plik APK zawierający zasoby
dla wszystkich gęstości ekranu i nie zawiera
<compatible-screens>
. Opublikuj
wraz z pakietami APK dla określonej gęstości, aby utworzyć plik zastępczy
urządzeń, które nie pasują do plików APK z parametrem
<compatible-screens>
.
Ten przykład pozwala wygenerować oddzielny plik APK dla każdego
ekran
gęstość oprócz ldpi
, xxhdpi
i
xxxhdpi
. Jest to możliwe dzięki użyciu funkcji exclude
do usuwania
te trzy gęstości z domyślnej listy wszystkich gęstości.
Odlotowe
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") } } }
Więcej informacji o dostosowywaniu różnych kompilacji wersji aplikacji na określone typy ekranów i urządzeń, zapoznaj się z Deklaruj ograniczenia obsługę ekranu.
Konfigurowanie wielu plików APK pod kątem interfejsów ABI
Aby tworzyć oddzielne pliki APK dla różnych interfejsów ABI, dodaj blok abi
wewnątrz
Blokada: splits
. W bloku abi
podaj listę
przy użyciu interfejsów ABI.
Poniższe opcje DSL narzędzia Gradle służą do konfigurowania wielu plików APK Interfejs ABI:
-
enable
w przypadku Groovy, aisEnable
dla skryptu Kotlin - Jeśli ustawisz ten element na
true
, Gradle wygeneruje wiele Pliki APK utworzone na podstawie zdefiniowanych przez Ciebie interfejsów ABI. Wartością domyślną jestfalse
. -
exclude
-
Określa rozdzieloną przecinkami listę interfejsów ABI, których Gradle nie ma używać
aby wygenerować osobne pliki APK. Aby wygenerować tag:
exclude
dla większości interfejsów ABI, ale musisz wykluczyć kilka interfejsów ABI, których nie obsługuje Twoja aplikacja . -
reset()
-
Czyści domyślną listę interfejsów ABI. Używaj tylko w połączeniu z
include
określający interfejsy ABI, które chcesz dodać.Ten fragment kodu ustawia listę interfejsów ABI tylko na
x86
ix86_64
, wywołując funkcjęreset()
w celu wyczyszczenia listy oraz następnie za pomocąinclude
: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
-
Określa rozdzieloną przecinkami listę interfejsów ABI, które mają generować pliki APK przez Gradle
. Używaj tylko w połączeniu z właściwością
reset()
, aby określić dokładne z listą interfejsów ABI. -
universalApk
w przypadku Groovy, aisUniversalApk
w przypadku pismo Kotlin -
Jeśli zasada ma wartość
true
, Gradle generuje oprócz pliki APK zgodne z interfejsem ABI. Uniwersalny plik APK zawiera kod i zasoby dla wszystkich interfejsów ABI w pojedynczy plik APK. Wartością domyślną jestfalse
.Pamiętaj, że ta opcja jest dostępne w bloku
splits.abi
. Podczas tworzenia wielu plików APK zgodnie z gęstością ekranu, Gradle zawsze generuje uniwersalny plik APK, zawiera kod i zasoby dla wszystkich gęstości ekranu.
Ten przykład pozwala wygenerować oddzielny plik APK dla każdego interfejsu ABI: x86
i x86_64
. Służy do tego funkcja reset()
zacznij od pustej listy interfejsów ABI, po której następuje ciąg include
i
listę interfejsów ABI, z których każdy otrzymuje pakiet APK.
Odlotowe
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 } } }
Listę obsługiwanych interfejsów ABI znajdziesz tutaj: Obsługiwane interfejsy ABI.
Projekty bez kodu natywnego/C++
W przypadku projektów bez kodu natywnego lub C++ panel Utwórz warianty zawiera 2 elementy kolumny: Module i Aktywna kompilacja Wariant, jak pokazano na ilustracji 1.
,
Rysunek 1. Panel Utwórz warianty zawiera 2 kolumny dotyczące projektów bez
kod natywny/kod C++.
Wartość Wariant aktywnej kompilacji dla: określa wariant kompilacji, który jest wdrożony i widoczny w edytorze. Aby przełączać się między wariantami, kliknij komórkę Aktywny wariant kompilacji modułu i wybierz na liście odpowiedni wariant.
Projekty z kodem natywnym/C++
W przypadku projektów z kodem natywnym lub C++ panel Utwórz warianty zawiera 3 elementy kolumny: Moduł i Aktywna kompilacja Wariant i Aktywny interfejs ABI, jak pokazano na ilustracji 2.
Rysunek 2. W panelu Utwórz warianty pojawi się kolumna Aktywny interfejs ABI:
projektów z kodem natywnym/C++.
Wartość Aktywnej kompilacji dla modułu. określa wariant kompilacji, który został wdrożony i jest widoczny w edytorze. W przypadku modułów natywnych wartość Aktywny interfejs ABI określa interfejs ABI, który edytor ale nie ma wpływu na to, co jest wdrażane.
Aby zmienić typ kompilacji lub interfejs ABI:
- Kliknij komórkę aktywnej kompilacji. lub Active ABI.
- Wybierz z listy odpowiedni wariant lub interfejs ABI . Automatycznie zostanie uruchomiona nowa synchronizacja.
Zmiana jednej z kolumn w module aplikacji lub biblioteki spowoduje zastosowanie zmiany do wszystkich wiersze zależne.
Skonfiguruj obsługę wersji
Domyślnie, gdy Gradle generuje wiele plików APK, każdy z nich ma taki sam
zgodnie z informacjami o wersji, które są określone na poziomie modułu,
build.gradle
lub build.gradle.kts
. Ponieważ
W Sklepie Google Play nie można mieć wielu plików APK tej samej aplikacji, które wszystkie zawierają
o takich samych informacjach o wersji, musisz upewnić się, że każdy plik APK ma unikalny identyfikator
versionCode
przed przesłaniem aplikacji do Sklepu Play.
Plik build.gradle
na poziomie modułu możesz skonfigurować tak,
zastąp versionCode
dla każdego pliku APK. Tworząc mapowanie
przypisującej unikalną wartość liczbową do każdego skonfigurowanego interfejsu ABI i gęstości
dla wielu plików APK, możesz zastąpić kod wersji wyjściowej wartością określającą
łączy kod wersji zdefiniowany w zasadzie defaultConfig
lub
Blok productFlavors
z wartością numeryczną przypisaną do funkcji
lub interfejs ABI.
W poniższym przykładzie pakiet APK dla interfejsu ABI x86
uzyskuje versionCode
z 2004 r. i interfejs x86_64
ABI
otrzyma versionCode
o wartości 3004.
Przypisanie kodów wersji dużymi przyrostami, na przykład 1000, pozwala
przypisać później unikalne kody wersji, aby zaktualizować aplikację. Dla:
jeśli na przykład defaultConfig.versionCode
wykona w parametrze
po kolejnej aktualizacji Gradle przypisuje wartość versionCode
z 2005 r.
plik APK x86
i kod 3005 do pliku APK x86_64
.
Wskazówka: jeśli kompilacja zawiera uniwersalny plik APK, przypisz do niego
versionCode
to wynik niższy niż w przypadku jakiegokolwiek innego pliku APK.
Ponieważ Sklep Google Play instaluje Twoją aplikację, która jest
jest zgodny z urządzeniem docelowym i ma najwyższą
versionCode
, przypisuję niższą wartość versionCode
do
który gwarantuje, że Sklep Google Play spróbuje zainstalować jedną z Twoich
plików APK. Poniżej znajduje się przykładowy kod.
zajmuje się tym, nie zastępując uniwersalnego pakietu APK
domyślna wartość versionCode
.
Odlotowe
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)) } } } }
Więcej przykładów schematów kodu wersji alternatywnych znajdziesz w artykule Przypisanie kodów wersji.
Tworzenie wielu plików APK
Po skonfigurowaniu modułu build.gradle
lub
build.gradle.kts
pliku, aby utworzyć kilka plików APK, kliknij
Kompilacja > Utwórz plik APK, by utworzyć wszystkie pakiety APK przeznaczone
wybrany moduł w panelu Projekt. Gradle tworzy pliki APK
dla każdej gęstości lub interfejsu ABI w: build/outputs/apk/
projektu
katalogu.
Gradle tworzy plik APK dla każdej gęstości lub interfejsu ABI, dla którego skonfigurujesz wiele plików APK. Jeśli włączysz wiele plików APK zarówno dla gęstości, jak i interfejsów ABI, Gradle utworzy plik APK dla każdej kombinacji gęstości i interfejsu ABI.
Na przykład:
Fragment kodu build.gradle
umożliwia tworzenie wielu plików APK dla usług mdpi
oraz
Gęstości: hdpi
, a także interfejsy ABI x86
i x86_64
:
Odlotowe
... 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") } }
Dane wyjściowe przykładowej konfiguracji zawierają te 4 pliki APK:
app-hdpiX86-release.apk
: zawiera kod i zasoby dla języka: Gęstośćhdpi
ix86
ABI.app-hdpiX86_64-release.apk
: zawiera kod i zasoby dla języka: Gęstośćhdpi
ix86_64
ABI.app-mdpiX86-release.apk
: zawiera kod i zasoby dla języka: Gęstośćmdpi
ix86
ABI.app-mdpiX86_64-release.apk
: zawiera kod i zasoby dla języka: Gęstośćmdpi
ix86_64
ABI.
W przypadku tworzenia wielu plików APK opartych na gęstości ekranu Gradle zawsze generuje uniwersalny plik APK, który zawiera kod i zasoby dla wszystkich gęstości, a także pakiety APK dla poszczególnych gęstości.
Podczas tworzenia wielu plików APK na podstawie
ABI, Gradle generuje tylko plik APK zawierający kod i zasoby dla wszystkich
Interfejsy ABI, jeśli określisz universalApk true
w parametrze
Blok splits.abi
w pliku build.gradle
(dla Groovy) lub isUniversalApk = true
w
Blok splits.abi
w pliku build.gradle.kts
(dla skryptu Kotlin).
Format nazwy pliku APK
Podczas tworzenia wielu plików APK Gradle generuje nazwy plików APK za pomocą tych reguł: schemat:
modulename-screendensityABI-buildvariant.apk
Elementy schematu to:
-
modulename
- Określa nazwę tworzonego modułu.
-
screendensity
-
Jeśli włączonych jest wiele plików APK gęstości ekranu, określa ekran
dla pliku APK, np.
mdpi
. -
ABI
-
Jeśli włączonych jest wiele plików APK dla ABI, określa interfejs ABI dla pliku APK, np. jako
x86
.Jeśli włączonych jest wiele plików APK zarówno dla gęstości ekranu, jak i interfejsu ABI, Gradle łączy nazwę gęstości z nazwą interfejsu ABI, np.
mdpiX86
Jeśli włączono interfejsuniversalApk
dla poszczególnych interfejsów ABI plików APK, Gradle używa wersjiuniversal
jako części ABI uniwersalnego pliku APK nazwa pliku. -
buildvariant
-
Określa kompilowany wariant kompilacji, np.
debug
.
Na przykład podczas tworzenia mdpi
pakietu APK o gęstości ekranu dla aplikacji
wersja myApp do debugowania, nazwa pliku APK to
myApp-mdpi-debug.apk
Premiera
czyli w wersji myApp skonfigurowanej do tworzenia wielu plików APK dla
Gęstość ekranu mdpi
i interfejs ABI x86
ma nazwę pliku APK
myApp-mdpiX86-release.apk