Na tej stronie dowiesz się, jak skonfigurować warianty kompilacji, aby Tworzenie różnych wersji aplikacji z jednego projektu aby umożliwić prawidłowe zarządzanie zależnościami i konfiguracjami podpisywania.
Każdy wariant kompilacji reprezentuje inną wersję aplikacji, która które możesz stworzyć. Możesz na przykład utworzyć jedną wersję swojej aplikacji czyli bezpłatną z ograniczonym zestawem treści, oraz inną płatną wersję, zawiera więcej informacji. Możesz też tworzyć różne wersje aplikacji kierowane w zależności od poziomu interfejsu API lub innych wersji urządzeń.
Warianty kompilacji są wynikiem działania Gradle korzystającego z określonego argumentu do łączenia ustawień, kodu i zasobów skonfigurowanych w rodzajów budowy i smaków produktów. Chociaż nie konfigurujesz wariantów kompilacji musisz skonfigurować typy kompilacji i smaki produktów, które z nich korzystają.
Przykład: „demonstracja” rodzaj usługi może określać określone funkcje.
i wymagań urządzeń, takich jak niestandardowy kod źródłowy, zasoby
poziomy interfejsu API, podczas gdy typ kompilacji pozwala zastosować różne kompilacje i
ustawień pakietów, takich jak opcje debugowania i klucze podpisywania.
wariantem kompilacji, który łączy te 2 elementy, jest „demoDebug” wersji Twojej aplikacji i zawiera
kombinacja konfiguracji i zasobów zawartych w „prezentacji”
rodzaj produktu, „debugowanie” typ kompilacji i main/
zbiór źródeł.
Skonfiguruj typy kompilacji
Typy kompilacji możesz tworzyć i konfigurować w android
pliku build.gradle.kts
na poziomie modułu. Gdy tworzysz
nowego modułu, Android Studio automatycznie utworzy kompilację do debugowania i kompilacji.
. Mimo że typ kompilacji do debugowania nie jest widoczny w konfiguracji kompilacji
Android Studio skonfiguruje go za pomocą debuggable
true
. Pozwala to na debugowanie aplikacji na bezpiecznych urządzeniach z Androidem
konfiguruje podpisywanie aplikacji za pomocą ogólnego magazynu kluczy debugowania.
Jeśli chcesz dodać do konfiguracji typ kompilacji do debugowania
lub zmienić określone ustawienia. Poniższy przykład określa
applicationIdSuffix
dla typu i konfiguracji kompilacji do debugowania
„etap przejściowy” typ kompilacji inicjowany z użyciem ustawień typu kompilacji do debugowania:
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" } } }
Odlotowe
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" } } }
Uwaga: gdy wprowadzasz zmiany w pliku konfiguracji kompilacji,
Android Studio wymaga zsynchronizowania projektu z nowym
konfiguracji. Aby zsynchronizować projekt, kliknij Sync Now (Synchronizuj teraz).
na pasku powiadomień, który pojawia się po wprowadzeniu zmiany lub kliknięciu
Synchronizuj projekt na pasku narzędzi. Jeśli Android
Studio wykrywa błędy w konfiguracji,
Pojawi się okno Wiadomości opisujące problem.
Aby dowiedzieć się więcej o wszystkich właściwościach, które można skonfigurować za pomocą typów kompilacji,
przeczytaj
BuildType
.
Skonfiguruj smaki produktów
Tworzenie smaków produktów przypomina tworzenie typów kompilacji. Dodaj smaki produktów do
Blok productFlavors
w konfiguracji kompilacji i uwzględnić odpowiednie ustawienia.
Gromady produktów obsługują te same właściwości, co
defaultConfig
, ponieważ defaultConfig
należy do
ProductFlavor
. Oznacza to, że możesz
podać podstawowe dane
konfigurację dla wszystkich smaków w bloku defaultConfig
,
każdy rodzaj może zmienić dowolną z tych wartości domyślnych, np. applicationId
. Do
więcej informacji o identyfikatorze aplikacji znajdziesz w artykule
Ustaw identyfikator aplikacji.
Uwaga: nadal musisz określić nazwę pakietu za pomocą atrybutu
package
.
w pliku manifestu main/
. Musisz także użyć tego atrybutu
nazwy pakietu w kodzie źródłowym, aby odwołać się do klasy R
lub rozwiązać
względną aktywność lub rejestrację usługi. Dzięki temu możesz używać
applicationId
, aby nadać każdemu rodzajowi produktu unikalny identyfikator
sposobu prezentacji i dystrybucji bez konieczności zmiany kodu źródłowego.
Wszystkie smaki muszą należeć do nazwanego wymiaru smaku, który jest grupą smaków produktów. Musisz przypisać wszystkie smaki do wymiaru smaku; W przeciwnym razie pojawi się następujący błąd kompilacji.
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
Jeśli dany moduł określa tylko 1 wymiar, wtyczka Androida do obsługi Gradle automatycznie przypisuje do danego wymiaru wszystkie cechy danego modułu.
.
Poniższy przykładowy kod tworzy wymiar rodzaju o nazwie „version” i dodaje
„demo” i „pełny” smaków produktów. Te smaki dają
applicationIdSuffix
i
versionNameSuffix
:
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" } } }
Odlotowe
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" } } }
Uwaga: jeśli masz starszą aplikację (utworzoną przed
sierpień 2021 r.), które rozpowszechniasz za pomocą plików APK w Google Play, aby dystrybuować aplikację za pomocą wielu plików APK.
support w Google Play, przypisz tę samą wartość applicationId
do wszystkich wariantów i przydzielić każdemu z nich inny
versionCode
Do rozpowszechniania
różnych wersji aplikacji jako osobnych aplikacji w Google Play, musisz przypisać
różne applicationId
w każdej z wariantów.
Po utworzeniu i skonfigurowaniu odmian produktów kliknij Synchronizuj
teraz na pasku powiadomień. Po zakończeniu synchronizacji Gradle
automatycznie tworzy warianty kompilacji na podstawie typu kompilacji i produktu
smaków i nazwanych według
<product-flavor><Build-Type>
Jeśli na przykład
utworzono „demonstracja” i „pełny” produktów z funkcją wartości domyślnej
„debuguj” oraz
„release” typów kompilacji, Gradle tworzy te warianty kompilacji:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
Aby wybrać wariant kompilacji do skompilowania uruchom, kliknij Kompilacja > Wybierz Utwórz wariant i wybierz wariant kompilacji z menu. Aby zacząć dostosowywać każdy wariant kompilacji, dodając do niego własne funkcje, musisz utworzyć źródło i nim zarządzać zestawień, jak opisano na tej stronie.
Zmienianie identyfikatora aplikacji dla wariantów kompilacji
Gdy tworzysz pakiet APK lub AAB dla swojej aplikacji, narzędzia do kompilacji oznaczają aplikację tagiem
identyfikator aplikacji zdefiniowany w bloku defaultConfig
w tabeli build.gradle.kts
zgodnie z poniższym przykładem. Jeśli jednak chcesz utworzyć różne wersje pliku
wyświetlać się jako osobne strony w Sklepie Google Play (np. „bezpłatna”) i „profesjonalista”
, musisz utworzyć oddzielne
utwórz warianty, które różnią się
identyfikator aplikacji.
W tym przypadku zdefiniuj każdy wariant kompilacji jako osobny
smak produktu. Dla każdego smaku
wewnątrz bloku productFlavors
można ponownie zdefiniować applicationId
możesz też dołączyć segment do domyślnego identyfikatora aplikacji
przy użyciu funkcji applicationIdSuffix
, jak pokazano tutaj:
Kotlin
android { defaultConfig { applicationId = "com.example.myapp" } productFlavors { create("free") { applicationIdSuffix = ".free" } create("pro") { applicationIdSuffix = ".pro" } } }
Odlotowe
android { defaultConfig { applicationId "com.example.myapp" } productFlavors { free { applicationIdSuffix ".free" } pro { applicationIdSuffix ".pro" } } }
W ten sposób identyfikator aplikacji dla „bezpłatnej” smak produktu to „com.example.mojaaplikacja.free”.
Możesz też użyć parametru applicationIdSuffix
, aby dołączyć segment na podstawie
typ kompilacji, jak tutaj:
Kotlin
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
Odlotowe
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
Ponieważ Gradle stosuje konfigurację typu kompilacji po rodzaju usługi, identyfikator aplikacji „bezpłatne debugowanie”; wariant kompilacji to „com.example.mojaaplikacja.free.debug”. Jest to przydatne, gdy chcesz mieć zarówno na tym samym urządzeniu, na którym są debugowane i kompilowane, bo żadne dwie aplikacje nie mogą mieć ten sam identyfikator aplikacji.
Jeśli masz starszą aplikację (utworzoną przed sierpniem) 2021), którą rozpowszechniasz w Google Play za pomocą plików APK i chcesz użyć tych samych informacji o aplikacji do dystrybuować wiele plików APK, są kierowane na inną konfigurację urządzenia, np. na poziom API, użyj tego samego identyfikatora aplikacji dla każdego wariantu kompilacji, ale przy każdym Plik APK zawiera inny plikversionCode
. Więcej informacji:
Obsługa wielu plików APK. Publikowanie
nie wpływa to na pakiety aplikacji na Androida, ponieważ
korzysta on z jednego artefaktu
kod wersji i identyfikator aplikacji.
Wskazówka: jeśli musisz podać identyfikator aplikacji w
pliku manifestu, możesz użyć zmiennej ${applicationId}
w dowolnym
w pliku manifestu. Podczas kompilacji Gradle zastępuje ten tag rzeczywistym
identyfikator aplikacji. Więcej informacji znajdziesz w sekcji Wstawianie kompilacji
do pliku manifestu.
Łącz różne smaki produktów z wymiarami smakowymi
W niektórych przypadkach warto połączyć konfiguracje różnych usług smaków. Możesz na przykład utworzyć różne konfiguracje dla „pełny” i „demo” smaki produktów oparte na poziomie interfejsu API. Aby to zrobić: dzięki wtyczce Androida do obsługi Gradle możesz utworzyć wiele grup smaków produktów wymiarów.
Podczas tworzenia aplikacji Gradle łączy usługę konfiguracji smaku z każdego zdefiniowanego wymiaru, a także konfiguracji typu kompilacji, aby utworzyć ostateczny wariant kompilacji. Gradle nie łączyć smaki produktów należące do tych samych wymiarów smaku.
Poniższa próbka kodu korzysta z
flavorDimensions
, aby utworzyć „tryb”. smak
do grupowania „pełnych” danych, i „demo” smaki produktów i „interfejs API” smak
wymiar, aby pogrupować konfiguracje typów produktów na podstawie poziomu interfejsu API:
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" ... } } } ...
Odlotowe
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" ... } } } ...
Liczba wariantów kompilacji utworzonych przez Gradle jest równa iloczynowi parametru liczbę smaków w każdym wymiarze smaku oraz liczbę typów konstrukcji, konfiguracji. Gdy Gradle nadaje nazwę każdemu wariantowi kompilacji lub powiązanym z nim artefaktom, smaki należące do wymiaru o wyższym priorytecie pojawiają się jako pierwsze, a po nich występują tych z wymiarów o niższym priorytecie, a po nich typ kompilacji.
Zastosowanie zgodnie z poprzednią konfiguracją kompilacji, Gradle tworzy w sumie 12, kompiluj warianty o tym schemacie nazewnictwa:
- Wariant kompilacji:
[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
- Powiązany plik APK:
app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
- Na przykład
- Wariant kompilacji:
minApi24DemoDebug
- Powiązany plik APK:
app-minApi24-demo-debug.apk
Oprócz katalogów zbioru źródłowego, które możesz tworzyć dla poszczególnych
rodzaju produktu i wersji kompilacji, można również tworzyć katalogi zbiorów źródłowych,
dla każdej kombinacji smaków produktów. Możesz na przykład utworzyć
i dodasz źródła Java do katalogu src/demoMinApi24/java/
,
a Gradle używa tych źródeł tylko podczas tworzenia wariantu, który łączy
te 2 różne smaki.
Zbiory źródłowe, które tworzysz dla rodzaju produktów kombinacje mają wyższy priorytet niż zbiory źródłowe, które należą do poszczególnych smak poszczególnych produktów. Aby dowiedzieć się więcej o zbiorach źródłowych i sposobie Gradle scala zasoby, przeczytaj sekcję na temat tworzenia .
Filtruj warianty
Gradle tworzy wariant kompilacji dla każdej możliwej kombinacji produktu
smaki i typy kompilacji. Jednak w pewnych okolicznościach
i tworzyć warianty, których nie potrzebujesz lub które nie mają sensu
i kontekstu projektu. Aby usunąć określone konfiguracje wariantów kompilacji:
utwórz filtr wariantu w build.gradle.kts
na poziomie modułu
.
Na przykładzie konfiguracji kompilacji z poprzedniej sekcji
załóżmy, że na potrzeby wersji demonstracyjnej chcesz obsługiwać tylko interfejsy API poziomu 23 i wyższych
wersji aplikacji. Za pomocą
variantFilter
, aby odfiltrować cały wariant kompilacji
konfiguracje, które łączą interfejs „minApi21” i „demo” smaki produktu:
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 } } } ...
Odlotowe
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) } } } ...
Gdy dodasz do konfiguracji kompilacji filtr wariantu i kliknij Synchronizuj
Teraz na pasku powiadomień Gradle ignoruje warianty kompilacji, które spełniają
na podanych warunkach. Warianty kompilacji nie pojawiają się już w menu
po kliknięciu Kompilacja > Na pasku menu wybierz Utwórz wariant.
lub Utwórz warianty w
pasku narzędzi.
Tworzenie zbiorów źródłowych
Domyślnie Android Studio tworzy main/
zbiór źródeł i katalogi dla
wszystko, co chcesz udostępniać między wszystkimi wariantami kompilacji. Musisz jednak
mogą tworzyć nowe zbiory źródłowe, aby kontrolować, które pliki Gradle kompiluje i
pakiety do określonych typów kompilacji, smaków produktów, kombinacji
smaków (gdy używasz atrybutu smak)
wymiarów) i tworzenia wariantów.
Możesz na przykład zdefiniować podstawowe
funkcje w zbiorze źródłowym main/
i wykorzystaj rodzaj produktu
zestawy źródeł umożliwiające zmianę marki aplikacji w przypadku różnych klientów;
uwzględniaj specjalne uprawnienia i funkcje logowania tylko w przypadku wariantów kompilacji
korzystających z typu kompilacji do debugowania.
Gradle wymaga, aby pliki i katalogi zbioru źródłowego były uporządkowane w określonej
podobnie jak w zbiorze źródłowym main/
. Na przykład Gradle
wymaga plików klas Kotlin lub Javy, które są charakterystyczne dla
w katalogach src/debug/kotlin/
lub src/debug/java/
.
Wtyczka Androida do obsługi Gradle zapewnia przydatne zadanie Gradle, które pokazuje jak uporządkować pliki w przypadku poszczególnych typów budowli, smaki i tworzenia różnych wersji. Na przykład ten przykład z danych wyjściowych zadania opisuje, gdzie Gradle spodziewa się znaleźć określone pliki do „debugowania”. kompilacja typ:
------------------------------------------------------------ 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]
Aby wyświetlić dane wyjściowe, wykonaj te czynności:
- Kliknij Gradle na pasku okna narzędzi.
Przejdź do MyApplication (aplikacja) > Lista zadań > android oraz kliknij dwukrotnie sourceSets.
Aby wyświetlić folder Tasks, musisz pozwolić Gradle utworzyć listę zadań podczas synchronizacji. Aby to zrobić:
- Kliknij Plik > Ustawienia > Funkcja eksperymentalna (Android Studio > Ustawienia > Eksperymentalne) w systemie macOS).
- Odznacz Nie listę zadań Gradle podczas synchronizacji.
- Po wykonaniu zadania Gradle otworzy się okno Uruchom z wyświetlonym dane wyjściowe.
Uwaga: w danych wyjściowych zadania znajdziesz też informacje o tym, jak uporządkować zbiory źródłowe.
plików, których chcesz użyć do testowania aplikacji, np.
test/
i androidTest/
testowania zbiorów źródłowych.
Gdy utworzysz nowy wariant kompilacji, Android Studio nie utworzy źródła
ustawić katalogi, ale udostępnia kilka opcji, które mogą Ci pomóc. Dla:
Aby na przykład utworzyć katalog java/
na potrzeby debugowania
typ kompilacji:
- Otwórz panel Projekt i wybierz Widok projektu w menu u góry panelu.
- Wejdź na
MyProject/app/src/
. - Kliknij prawym przyciskiem myszy katalog
src
i wybierz Nowość > Katalog - W menu w sekcji Zestawy źródeł Gradle wybierz full/java.
- Naciśnij Enter.
Android Studio tworzy katalog zbioru źródłowego dla typu kompilacji do debugowania oraz
a następnie utworzy w nim katalog java/
. Ewentualnie
Android Studio może utworzyć katalogi, gdy dodasz nowy plik do
projektu dla konkretnego wariantu kompilacji.
Aby np. utworzyć plik XML z wartościami dla „debugowania” typ kompilacji:
- W panelu Projekt kliknij prawym przyciskiem myszy
src
i wybierz New (Nowy) > XML > Plik XML wartości. - Wpisz nazwę pliku XML lub zachowaj nazwę domyślną.
- W menu Docelowy zestaw źródeł wybierz debugowanie.
- Kliknij Zakończ.
Parametr „debugowanie” typ kompilacji został określony jako docelowy zbiór źródeł, Android Studio automatycznie tworzy niezbędne katalogi, który utworzy plik XML. Powstała struktura katalogów będzie wyglądać tak rysunek 1.
![](https://developer.android.com/static/images/tools/debug-directories_2-1_2x.png?authuser=0000&hl=pl)
Rysunek 1. Nowe katalogi zbiorów źródłowych na potrzeby „debugowania” kompilacja typu.
Aktywne zestawy źródeł mają zielony wskaźnik na ikonie wskazujący, że są aktywne.
Zbiór źródłowy debug
ma sufiks [main]
, co oznacza, że zostanie scalony
do zbioru źródłowego main
.
Wykonując tę samą procedurę, możesz również utworzyć katalogi zbiorów źródłowych dla:
typów produktów, np. src/demo/
, i wersji kompilacji, takich jak
src/demoDebug/
Można również tworzyć zestawy źródeł testowych
kierowane na określone warianty kompilacji,
src/androidTestDemoDebug/
Więcej informacji:
testowania zbiorów źródłowych.
Zmień konfiguracje domyślnego zestawu źródeł
Jeśli masz źródła, które nie są uporządkowane w pliku domyślnego zestawu źródeł
struktury, której oczekuje Gradle, zgodnie z opisem w poprzedniej sekcji na temat
tworząc zbiory źródłowe, możesz użyć funkcji
sourceSets
, aby zmienić miejsce, w którym Gradle ma zbierać dane
dla poszczególnych komponentów zbioru źródłowego.
Blok sourceSets
musi być
w bloku android
. Nie musisz przenosić
pliki źródłowe; wystarczy podać w Gradle tylko ścieżki względem
build.gradle.kts
na poziomie modułu, gdzie Gradle może
pliki przypisane do poszczególnych komponentów zbioru źródłowego. Aby dowiedzieć się, które komponenty
i określić, czy można je zmapować na wiele plików lub katalogów,
zobacz dokumentację API wtyczki Android Gradle.
Ten przykładowy kod mapuje źródła z katalogu app/other/
do niektórych komponentów zbioru źródłowego main
i zmienia wartość
katalog główny zestawu źródłowego androidTest
:
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") ... } } ...
Odlotowe
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' ... } } } ...
Pamiętaj, że katalog źródłowy może należeć tylko do jednego zbioru źródłowego. Na przykład nie można udostępnić
te same źródła testowe z zbiorami źródłowymi test
i androidTest
. Ten
jest to, że Android Studio tworzy osobne moduły IntelliJ dla każdego zbioru źródłowego i nie może obsługiwać
zduplikowanych źródeł treści w zbiorach źródłowych.
Tworzenie z użyciem zbiorów źródłowych
Katalogi zbioru źródłowego mogą zawierać kod i zasoby które chcesz spakować tylko z określonymi konfiguracjami. Jeśli na przykład jesteś tworząc plik „demoDebug” wariant kompilacji, który jest iloczynem krzyżowym atrybutu „demo” rodzaj produktu i „debugowanie” typu kompilacji, Gradle przygląda się i nadaje im następujący priorytet:
-
src/demoDebug/
(zestaw źródeł wariantów kompilacji) -
src/debug/
(zestaw źródłowy typu kompilacji) -
src/demo/
(zestaw źródeł smaku produktu) -
src/main/
(zestaw głównego źródła)
Zbiory źródłowe utworzone dla kombinacji smaków produktów muszą zawierać wszystkie wymiary smaków. Na przykład zbiór źródeł wersji kompilacji musi być kombinacją typu kompilacji i wszystkich typów wymiarów. Scalanie kodu i zasobów obejmujących foldery, które obejmują wiele, ale nie wszystkie nie są obsługiwane.
Jeśli połączysz kilka produktów
smaków, priorytet między smakami produktu zależy od smaku.
wymiarów, do których należą. Gdy wyświetla się wymiary smaku z atrybutem
android.flavorDimensions
, a także smaki produktów, które
należą do pierwszego podanego przez Ciebie wymiaru smaku, który ma wyższy priorytet niż
należące do drugiego wymiaru smaku i tak dalej. Dodatkowo:
zestawy źródłowe tworzone dla kombinacji smaków produktów mają wyższy
niż zbiory źródłowe, które należą do konkretnego smaku produktów.
Kolejność priorytetów określa, który zbiór źródłowy ma wyższy
gdy Gradle łączy kod i zasoby. Ponieważ demoDebug/
katalog zbioru źródłowego prawdopodobnie zawiera pliki, które są specyficzne dla tej kompilacji
wariantu, jeśli demoDebug/
zawiera plik zdefiniowany również w
debug/
, Gradle używa pliku w folderze demoDebug/
zbiór źródeł. Podobnie Gradle udostępnia pliki w typie kompilacji i rodzaju usługi.
źródło ma wyższy priorytet niż te same pliki w usłudze main/
.
Gradle uwzględnia tę kolejność priorytetów podczas stosowania tych reguł kompilacji:
- Cały kod źródłowy w katalogach
kotlin/
ijava/
jest skompilowany razem, aby wygenerować jeden wynik.Uwaga: w przypadku danego wariantu kompilacji Gradle przesyła kompilację jeśli natrafi na co najmniej 2 katalogi zbioru źródłowego, które zostały zdefiniowane tę samą klasę Kotlin lub Java. Na przykład podczas tworzenia aplikacji do debugowania nie można zdefiniować zarówno
src/debug/Utility.kt
, jak isrc/main/Utility.kt
, ponieważ Gradle sprawdza tych katalogów w procesie kompilacji i zwraca „zduplikowaną klasę” . Jeśli chcesz mieć różne wersje usługiUtility.kt
dla różnych typów kompilacji, każdy z nich musi definiować własną wersję pliku i nie uwzględniaj go w zbiorze źródłowymmain/
. - Pliki manifestu są scalone w jeden plik manifestu. Nadaj priorytet w takiej samej kolejności jak na liście w poprzednim przykładzie. Oznacza to, że ustawienia w pliku manifestu kompilacji zastępują ustawienia w pliku manifestu dla rodzaju produktów i tak dalej. Aby się uczyć znajdziesz więcej informacji o scalaniu manipulacji.
- Pliki w katalogach
values/
są scalane razem. Jeśli 2 pliki mają taką samą nazwę, np. 2 plikistrings.xml
, priorytet jest przyznawany w takiej samej kolejności jak z listy z poprzedniego przykładu. Oznacza to, że wartości zdefiniowane w pliku w zbiorze źródłowym typu kompilacji zastąpią wartości zdefiniowane w tym samym pliku w rodzaju produktu itd. - Zasoby w katalogach
res/
iasset/
są łączone w pakiety. Jeśli istnieją zasoby o tej samej nazwie zdefiniowane w co najmniej dwa zbiory źródłowe, priorytet jest nadany w tej samej kolejności co lista z poprzedniego przykładu. - Gradle udostępnia zasoby i pliki manifestu dołączone do biblioteki które mają najniższy priorytet przy tworzeniu aplikacji.
Deklarowanie zależności
Aby skonfigurować zależność dla określonego wariantu kompilacji lub
testowania zbioru źródeł źródłowych,
poprzedź nazwę wariantu kompilacji lub zbioru źródeł testowania przed
Implementation
słowo kluczowe, tak jak w tym przykładzie:
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.5.1") }
Odlotowe
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.5.1' }
Więcej informacji o konfigurowaniu zależności znajdziesz Więcej informacji znajdziesz w artykule Dodawanie zależności kompilacji.
Zarządzanie zależnościami z uwzględnieniem wariantów
Wtyczka Androida do obsługi Gradle w wersji 3.0.0 lub nowszej zawiera nowy mechanizm zależności, który automatycznie
dopasowuje warianty podczas korzystania z biblioteki. Oznacza to, że ma ona debug
wariant aplikacji.
automatycznie pobiera wariant debug
biblioteki i tak dalej. Działa też, gdy używasz
smaki: wariant aplikacji freeDebug
będzie używać tego pola freeDebug
biblioteki
wersji.
Aby wtyczka dokładnie dopasowywała wersje, musisz: udostępniać pasujące wartości zastępcze, jak opisano w poniżej, gdy bezpośrednie dopasowanie nie jest możliwe.
Załóżmy na przykład, że aplikacja konfiguruje typ kompilacji o nazwie „etap przejściowy”, ale jeden z tych zależne od biblioteki. Gdy wtyczka próbuje utworzyć „staging” wersji nie wie, której wersji biblioteki użyć, i zobaczysz podobny komunikat o błędzie na:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
Naprawianie błędów kompilacji związanych z dopasowaniem wariantów
Wtyczka zawiera elementy DSL, które pomagają kontrolować sposób rozpoznawania sytuacji przez Gradle w którym przypadku bezpośrednie dopasowanie wariantu aplikacji do zależności jest niemożliwe.
Poniżej znajdziesz listę problemów związanych z dopasowywaniem zależności uwzględniających warianty oraz sposobem aby rozwiązać je przy użyciu właściwości DSL:Aplikacja zawiera typ kompilacji, którego nie ma zależność biblioteczna.
Na przykład aplikacja zawiera element „przejściowy” ale zależność obejmuje tylko „debuguj” i „release” typów kompilacji.
Zwróć uwagę, że problem nie występuje, gdy zależność biblioteki zawiera kompilację których Twoja aplikacja nie obsługuje. To dlatego, że wtyczka nigdy żądań, które kompilują typ z zależności.
Użyj
matchingFallbacks
, aby określić alternatywne dopasowania dla danego typu kompilacji. jak tutaj: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") } } }
Odlotowe
// 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'] } } }
W przypadku danego wymiaru smaku, który występuje zarówno w aplikacji, jak i w jej bibliotece aplikacja zawiera smaki, których nie ma biblioteka.
Na przykład zależności aplikacji i jej biblioteki obejmują „poziom” smaku. Opcja „Poziom” wymiar w aplikacji zawiera słowo „bezpłatne” i „płatne” smaków, ale też zależność obejmuje tylko słowo „demo” i „płatne” smaków tego samego wymiaru.
Pamiętaj, że w przypadku danego wymiaru smaku występuje zarówno w aplikacji, jak i w jej bibliotece nie ma problemu, jeśli biblioteka zawiera rodzaj usługi, nie działa. Dzieje się tak, ponieważ wtyczka nigdy nie żąda tego rodzaju z zależności.
Użyj
matchingFallbacks
, aby określić alternatywne dopasowania słowa kluczowego „bezpłatne” w aplikacji smak produktu, jak tutaj: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") } } }
Odlotowe
// 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'] } } }
Zależność biblioteki obejmuje wymiar smaku, którego nie ma Twoja aplikacja.
Na przykład zależność biblioteki obejmuje smaki dla „minApi” ale Twoja aplikacja zawiera rodzaje tylko „poziomu” . Gdy chcesz utworzyć kod „freeDebug” wersji Twojej aplikacji, wtyczka nie wie, czy użyć parametru „minApi23Debug” lub „minApi18Debug” wersji zależności.
Pamiętaj, że problem nie występuje, jeśli aplikacja zawiera wymiar smaku określony w bibliotece. już nie. Dzieje się tak, ponieważ wtyczka pasuje tylko do wymiarów, które w zależności. Jeśli na przykład zależność nie zawiera wymiaru dla interfejsów ABI, kod „freeX86Debug” Twojej aplikacji używa parametru „freeDebug” wersji zależności.
Użyj
missingDimensionStrategy
w blokudefaultConfig
, aby określić domyślny rodzaj, który wtyczka wybiera dla każdego brakującego wymiaru, jak widać w z tego przykładu. Możesz też zastąpić swój wybór wproductFlavors
dzięki czemu każdy rodzaj może określać inną strategię dopasowania dla brakującego wymiaru.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") {} } }
Odlotowe
// 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 {} } }
Więcej informacji: matchingFallbacks
i missingDimensionStrategy
w dokumentacji DSL wtyczki Androida do obsługi Gradle.
Skonfiguruj ustawienia podpisywania
Gradle nie podpisuje pliku APK ani pakietu AAB kompilacji wersji, chyba że wyraźnie zdefiniujesz konfiguracji podpisywania tej kompilacji. Jeśli nie masz jeszcze klucza podpisywania, wygeneruj klucz przesyłania i magazyn kluczy w Android Studio.
Aby ręcznie skonfigurować konfiguracje podpisywania dla typu kompilacji wersji przy użyciu konfiguracji kompilacji Gradle:
- Utwórz magazyn kluczy. magazyn kluczy to plik binarny, który zawiera zestaw kluczy prywatnych. Magazyn kluczy musisz przechowywać w bezpiecznym miejscu. i bezpieczne miejsce.
- Utwórz klucz prywatny. klucz prywatny jest używany do podpisywania aplikacji. w celach rozpowszechniania i nigdy nie są dołączane do aplikacji ani ujawniane nieupoważnionym osobom trzecim.
-
Dodaj konfigurację podpisywania do
build.gradle.kts
na poziomie modułu plik:Kotlin
... android { ... defaultConfig {...} signingConfigs { create("release") { storeFile = file("myreleasekey.keystore") storePassword = "password" keyAlias = "MyReleaseKey" keyPassword = "password" } } buildTypes { getByName("release") { ... signingConfig = signingConfigs.getByName("release") } } }
Odlotowe
... android { ... defaultConfig {...} signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { ... signingConfig signingConfigs.release } } }
Uwaga: w tym hasła do klucza wersji i magazyn kluczy w pliku kompilacji nie jest dobrą praktyką dotyczącą bezpieczeństwa. Zamiast tego skonfiguruj plik kompilacji, aby uzyskiwać te hasła ze zmiennych środowiskowych lub poproś proces kompilacji haseł.
Aby uzyskać te hasła ze zmiennych środowiskowych:
Kotlin
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
Odlotowe
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
Magazyn kluczy możesz też załadować z pliku właściwości lokalnych. Ze względów bezpieczeństwa nie dodaj ten plik do elementu sterującego źródła. Zamiast tego skonfiguruj je lokalnie dla każdego Google Play. Więcej informacji można znaleźć na stronie Usuń dane podpisywania z plików kompilacji.
Po zakończeniu tego procesu możesz rozpowszechniać aplikację i ją opublikować w Google Play.
Ostrzeżenie: przechowuj magazyn kluczy i klucz prywatny w bezpiecznym i upewnić się, że masz bezpieczne kopie zapasowe. Jeśli używasz podpisywania aplikacji przez Google Play jeśli utracisz klucz przesyłania, poproś o zresetuj za pomocą Konsoli Play. Jeśli publikujesz aplikację bez podpisywania aplikacji przez Google Play (w przypadku aplikacji utworzonych przed sierpniem 2021 roku) oraz utracisz klucz podpisywania aplikacji, stracisz możliwość publikowania aktualizacji aplikacji, zawsze podpisywać wszystkie wersje aplikacji tym samym kluczem.
Podpisywanie aplikacji na Wear OS
Gdy publikujesz aplikacje na Wear OS, zarówno pakiet APK na zegarek, jak i opcjonalny plik APK na telefon muszą być podpisane ten sam klucz. Więcej informacji o pakowaniu i podpisywaniu aplikacji na Wear OS znajdziesz tutaj: Pakować i rozpowszechniać aplikacje na Wear.