Questa pagina mostra come configurare le varianti di build per Creare diverse versioni dell'app da un singolo progetto e per gestire correttamente le dipendenze e le configurazioni di firma.
Ogni variante della build rappresenta una versione diversa dell'app che che puoi creare. Ad esempio, potresti voler creare una versione della tua app che è senza costi con una serie limitata di contenuti e un'altra versione a pagamento ne include altri. Puoi anche creare versioni diverse della tua app che hanno come target dispositivi diversi, in base al livello API o ad altre varianti dei dispositivi.
Le varianti build sono il risultato dell'utilizzo di Gradle di regole per combinare impostazioni, codice e risorse tipi di build e gusti dei prodotti. Anche se non configuri le varianti della build direttamente, puoi configurare i tipi di build e le funzionalità di prodotto che li compongono.
Ad esempio, una "demo" product flavor potrebbe specificare determinate caratteristiche
e ai requisiti dei dispositivi, tra cui codice sorgente personalizzato, risorse e
i livelli API, mentre il comando "debug" tipo di build applica build e
impostazioni di pacchettizzazione, come le opzioni di debug e le chiavi di firma. La
la variante della build che combina questi due è la "demoDebug" della tua app e include un
combinazione delle configurazioni e delle risorse incluse nella "demo"
versione del prodotto, "debug" tipo di build e main/
set di origine.
Configura i tipi di build
Puoi creare e configurare tipi di build all'interno dell'android
del file build.gradle.kts
a livello di modulo. Quando crei
in un nuovo modulo, Android Studio crea automaticamente la build di debug e release
di testo. Il tipo di build di debug non viene visualizzato nella configurazione della build
, Android Studio la configura con debuggable
true
. In questo modo puoi eseguire il debug dell'app su dispositivi Android sicuri e
configura la firma dell'app con un archivio chiavi di debug generico.
Puoi aggiungere il tipo di build di debug alla configurazione se vuoi aggiungere
o modificare determinate impostazioni. Il seguente esempio specifica un
applicationIdSuffix
per il tipo di build di debug e configura
una gestione temporanea tipo di build inizializzato utilizzando le impostazioni del tipo di build di debug:
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" } } }
Alla moda
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" } } }
Nota:quando apporti modifiche a un file di configurazione di compilazione,
Android Studio richiede la sincronizzazione del progetto con il nuovo
configurazione. Per sincronizzare il progetto, fai clic su Sincronizza ora.
nella barra delle notifiche che appare quando apporti una modifica o fai clic
Sincronizza progetto dalla barra degli strumenti. Se Android
Studio rileva eventuali errori nella configurazione,
Viene visualizzata la finestra Messaggi per descrivere il problema.
Per scoprire di più su tutte le proprietà che puoi configurare con i tipi di build,
leggi
BuildType
.
Configura versioni dei prodotti
La creazione di versioni di prodotto è simile alla creazione di tipi di build. Aggiungi i sapori dei prodotti alla
productFlavors
nella configurazione della build e includi le impostazioni che preferisci.
Le versioni del prodotto supportano le stesse proprietà dei
defaultConfig
, perché defaultConfig
appartiene effettivamente
ProductFlavor
. Ciò significa che puoi fornire la base
configurazione per tutte le versioni nel blocco defaultConfig
e
ogni sapore può modificare uno qualsiasi di questi valori predefiniti, ad esempio applicationId
. A
per saperne di più sull'ID applicazione, consulta
Imposta l'ID applicazione.
Nota:devi comunque specificare un nome pacchetto utilizzando il metodo
package
:
nel file manifest main/
. Devi inoltre utilizzare
nome pacchetto nel codice sorgente per fare riferimento alla classe R
o per risolvere eventuali
attività relativa o registrazione di servizi. In questo modo puoi utilizzare
applicationId
per assegnare a ogni versione di prodotto un ID univoco per
la pacchettizzazione e la distribuzione senza dover modificare il codice sorgente.
Tutti i sapori devono appartenere a una dimensione denominata sapore, che è un gruppo sapori dei prodotti. Devi assegnare tutti i gusti a una dimensione sapore. altrimenti, riceverai il seguente errore di build.
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
Se un determinato modulo specifica solo una dimensione flavor, il plug-in Android Gradle assegna tutte le versioni del modulo a quella dimensione.
di Gemini Advanced.
Il seguente esempio di codice crea una dimensione flavor denominata "versione" e aggiunge
"demo" e "completo" sapori dei prodotti. Questi sapori offrono il loro
applicationIdSuffix
e
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" } } }
Alla moda
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" } } }
Nota: se hai un'app precedente (creata in precedenza
agosto 2021) che distribuisci tramite APK su Google Play per distribuire la tua app utilizzando più APK
assistenza in Google Play, assegna lo stesso valore applicationId
a tutte le varianti e assegnare a ciascuna variante
versionCode
. Per distribuire
diverse varianti della tua app come app separate in Google Play, devi assegnare
applicationId
diverso per ogni variante.
Dopo aver creato e configurato le versioni dei tuoi prodotti, fai clic su Sincronizza
Ora nella barra delle notifiche. Al termine della sincronizzazione, Gradle
crea automaticamente varianti di build in base ai tipi di build e al prodotto
e li assegna in base al nome
<product-flavor><Build-Type>
. Ad esempio, se
"demo" creata e "completo" versioni del prodotto mantenendo le impostazioni predefinite
"debug" e
"rilascia" tipi di build, Gradle crea le seguenti varianti di build:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
Per selezionare la variante di build da creare esegui, vai su Crea > Seleziona Variante build e poi una variante di build dal menu. Per iniziare a personalizzare ogni variante di build con le proprie funzionalità dovrai creare e gestire le risorse di origine personalizzati, come descritto in questa pagina.
Modificare l'ID applicazione per le varianti della build
Quando crei un APK o AAB per la tua app, gli strumenti di creazione codificano l'app con il token
ID applicazione definito nel blocco defaultConfig
da build.gradle.kts
come mostrato nell'esempio seguente. Tuttavia, se vuoi creare versioni diverse
vengano visualizzate come schede separate sul Google Play Store, ad esempio "senza costi" e "pro"
di Google Cloud, devi creare regole separate
generare varianti, ognuna con le sue caratteristiche
l'ID applicazione.
In questo caso, definisci ogni variante di build come una variante
sapore del prodotto. Per ogni gusto
All'interno del blocco productFlavors
, puoi ridefinire applicationId
oppure puoi aggiungere un segmento all'ID applicazione predefinito
utilizzando applicationIdSuffix
, come mostrato qui:
Kotlin
android { defaultConfig { applicationId = "com.example.myapp" } productFlavors { create("free") { applicationIdSuffix = ".free" } create("pro") { applicationIdSuffix = ".pro" } } }
Alla moda
android { defaultConfig { applicationId "com.example.myapp" } productFlavors { free { applicationIdSuffix ".free" } pro { applicationIdSuffix ".pro" } } }
In questo modo, l'ID applicazione per sapore del prodotto è "com.example.myapp.free".
Puoi anche utilizzare applicationIdSuffix
per aggiungere un segmento basato su
il tipo di build, come mostrato qui:
Kotlin
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
Alla moda
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
Poiché Gradle applica la configurazione del tipo di build in base alla versione del prodotto, l'ID applicazione per il "debug senza costi" la variante build è "com.example.myapp.free.debug". Questo è utile quando vuoi che siano il debug e la build della release sullo stesso dispositivo, perché due app non possono avere stesso ID applicazione.
Se hai un'app precedente (creata prima di agosto 2021) che distribuisci tramite APK su Google Play e vuoi usare la stessa scheda dell'app per distribuire diversi APK che ognuno ha come target una configurazione dispositivo diversa, ad esempio il livello API, devi utilizzare lo stesso ID applicazione per ogni variante di build, ma assegnare a ogni Esegui l'APK di un altroversionCode
. Per ulteriori informazioni, leggi le informazioni
Supporto di più APK. Pubblicazione in corso...
l'utilizzo di AAB non è interessato, poiché utilizza un singolo artefatto che usa una singola
il codice di versione e l'ID applicazione per impostazione predefinita.
Suggerimento:se devi fare riferimento all'ID applicazione nella
manifest, puoi utilizzare il segnaposto ${applicationId}
in qualsiasi
. Durante una build, Gradle sostituisce questo tag con il valore
l'ID applicazione. Per ulteriori informazioni, consulta Inserire build
nel file manifest.
Combinare più sapori di un prodotto con le relative dimensioni
In alcuni casi, potresti voler combinare le configurazioni di più prodotti sapori. Ad esempio, potresti voler creare configurazioni diverse per "completo" e "demo" versioni di prodotto basate sul livello API. Per farlo, il plug-in Android per Gradle consente di creare più gruppi di versioni di prodotto come sapore dimensioni.
Quando crea la tua app, Gradle combina un prodotto configurazione sapore da ogni dimensione sapore che definisci, insieme a un configurazione del tipo di build, per creare la variante finale. Gradle no combinare sapori di prodotti che appartengono alla stessa dimensione sapore.
Il seguente esempio di codice utilizza
flavorDimensions
per creare una "modalità" sapore
per raggruppare i valori "completi" e "demo" sapori del prodotto e una "api" sapore
dimensione per raggruppare le configurazioni delle versioni di prodotto in base al livello 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" ... } } } ...
Alla moda
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" ... } } } ...
Il numero di varianti di build create da Gradle è uguale al prodotto del il numero di versioni in ciascuna dimensione e il numero di tipi di build configurare. Quando Gradle assegna un nome a ogni variante di build o ad artefatti corrispondenti, I gusti che appartengono alla dimensione versione con priorità più elevata vengono visualizzati per primi, seguiti da quelle di dimensioni con priorità inferiore seguite dal tipo di build.
Utilizzo configurazione di build precedente come esempio, Gradle crea un totale di crea varianti con il seguente schema di denominazione:
- Variante build:
[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
- APK corrispondente:
app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
- Ad esempio,
- Variante build:
minApi24DemoDebug
- APK corrispondente:
app-minApi24-demo-debug.apk
Oltre al set di directory di origine che puoi creare per ogni
versione di prodotto e variante di build, puoi anche creare directory del set di origine
per ogni combinazione di sapori di prodotti. Ad esempio, puoi creare
e aggiungi origini Java alla directory src/demoMinApi24/java/
,
e Gradle le utilizza solo quando crea una variante che combina
queste due versioni di prodotto.
Set di origini che crei per la versione del prodotto le combinazioni hanno una priorità maggiore rispetto agli insiemi di sorgenti che appartengono a ogni il sapore del singolo prodotto. Per scoprire di più sui set di origini e su come Gradle unisce le risorse, leggi la sezione su come creare di origini dati.
Filtra varianti
Gradle crea una variante di build per ogni possibile combinazione del prodotto
versioni e tipi di build da te configurati. Tuttavia, potrebbero esserci alcune
creare varianti che non ti servono o che non hanno senso nel
contesto del tuo progetto. Per rimuovere determinate configurazioni di varianti di build,
crea un filtro delle varianti nell'elemento build.gradle.kts
a livello di modulo
.
Utilizzando come esempio la configurazione di compilazione della sezione precedente,
supponiamo che tu preveda di supportare solo i livelli API 23 e successivi per la demo
all'ultima versione dell'app. Puoi utilizzare lo
Blocco variantFilter
per filtrare tutte le varianti della build
configurazioni che uniscono "minApi21" e "demo" versioni del prodotto:
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 } } } ...
Alla moda
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) } } } ...
Dopo aver aggiunto un filtro delle varianti alla configurazione della build e aver fatto clic su Sincronizza
Ora, nella barra delle notifiche, Gradle ignora tutte le varianti di build che soddisfano
le condizioni specificate. Le varianti della build non vengono più visualizzate nel menu
quando fai clic su Crea > Seleziona Variante build dalla barra dei menu.
o Varianti build in
sulla barra della finestra degli strumenti.
Crea set di origini
Per impostazione predefinita, Android Studio crea main/
set di origine e directory per
tutto ciò che vuoi condividere tra tutte le varianti della build. Tuttavia,
creare nuovi set di origini per controllare esattamente quali file vengono compilati da Gradle
pacchetti per tipi di build specifici,
versioni di prodotto e combinazioni di
sapori dei prodotti (quando si utilizza sapore
dimensioni) e creare varianti.
Ad esempio, puoi definire
di funzionalità nel set di origini main/
e utilizza la versione di prodotto
set di fonti per modificare il branding della tua app per diversi clienti oppure
Includi autorizzazioni speciali e funzionalità di logging solo per le varianti della build
che utilizzano il tipo di build di debug.
Gradle si aspetta che i file e le directory dei set di origine siano organizzati in un
in modo simile al set di origini main/
. Ad esempio, Gradle
prevede file di classe Kotlin o Java specifici per il "debug" che il tipo di build
che si trova nelle directory src/debug/kotlin/
o src/debug/java/
.
Il plug-in Android per Gradle offre un'utile attività Gradle che mostra a organizzare i file per ciascuno dei tuoi tipi di build, e creare varianti. Ad esempio, il seguente esempio dell'output dell'attività descrive dove Gradle si aspetta di trovare determinati file per il "debug" creare tipo:
------------------------------------------------------------ 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]
Per visualizzare questo output, procedi come segue:
- Fai clic su Gradle nella barra della finestra degli strumenti.
Vai a MyApplication > (La mia applicazione) > Attività > Android e Fai doppio clic su sourceSets.
Per visualizzare la cartella Tasks, devi consentire a Gradle di creare elenco di attività durante la sincronizzazione. A tale scopo, procedi nel seguente modo:
- Fai clic su File > Impostazioni > Sperimentale (Android Studio > Impostazioni > Sperimentale su macOS).
- Deseleziona Non consentire creare l'elenco di attività Gradle durante la sincronizzazione Gradle.
- Dopo che Gradle ha eseguito l'attività, si apre la finestra Esegui per visualizzare come output.
Nota:l'output dell'attività mostra anche come organizzare i set di origini
per i file che vuoi utilizzare per eseguire test per la tua app, ad esempio
test/
e androidTest/
set di origini di test.
Quando crei una nuova variante della build, Android Studio non crea l'origine
impostare le directory al posto tuo, ma ti offre alcune opzioni utili. Per
esempio, per creare solo la directory java/
per il "debug"
tipo di build:
- Apri il riquadro Progetto e seleziona Vista Progetto dal menu nella parte superiore del riquadro.
- Vai a
MyProject/app/src/
. - Fai clic con il tasto destro del mouse sulla directory
src
e seleziona Nuovo > Directory. - Dal menu in Set di origini di Gradle, seleziona full/java.
- Premi Invio.
Android Studio crea una directory del set di origini per il tipo di build di debug e
quindi crea la directory java/
al suo interno. In alternativa,
Android Studio può creare le directory per te quando aggiungi un nuovo file
del tuo progetto per una specifica variante di build.
Ad esempio, per creare un file XML dei valori per il "debug" tipo di build:
- Nel riquadro Progetto, fai clic con il pulsante destro del mouse sull'
src
directory e seleziona Nuovo > XML > File XML dei valori. - Inserisci il nome del file XML o mantieni il nome predefinito.
- Nel menu accanto a Set di origini target, seleziona debug.
- Fai clic su Fine.
Poiché il comando "debug" il tipo di build è stato specificato come set di origini di destinazione Android Studio crea automaticamente le directory necessarie crea il file XML. La struttura della directory risultante figura 1.
![](https://developer.android.com/static/images/tools/debug-directories_2-1_2x.png?authuser=0000&hl=it)
Figura 1. Nuova directory del set di origini per "debug" creare di testo.
I set di origini attive sono contrassegnati da un indicatore verde nell'icona che indica che sono attivi. La
debug
set di origini ha come suffisso [main]
per indicare che verrà unito
nel set di origini main
.
Utilizzando la stessa procedura, puoi anche creare directory di set di origini
versioni del prodotto, ad esempio src/demo/
, e varianti di build, ad esempio
src/demoDebug/
. Inoltre, puoi creare set di origini di test
che hanno come target varianti di build specifiche, ad esempio
src/androidTestDemoDebug/
. Per saperne di più, consulta
set di origini di test.
Modifica le configurazioni predefinite del set di origini
Se hai origini non organizzate nel file del set di origini predefinito
strutturata prevista da Gradle, come descritto nella sezione precedente
creazione di set di origini, puoi utilizzare
.
Blocco sourceSets
per modificare il punto in cui Gradle cerca di radunarsi
per ogni componente di un set di origine.
Il blocco sourceSets
deve essere
nel blocco android
. Non è necessario spostare
i file sorgente; devi solo fornire a Gradle i percorsi relativi
file build.gradle.kts
a livello di modulo, in cui Gradle può
trovare i file per ciascun componente dell'insieme di origini. Per scoprire quali componenti puoi
configurarli e se puoi mapparli a più file o directory,
consulta il riferimento dell'API del plug-in Android Gradle.
Il seguente esempio di codice mappa le origini dalla directory app/other/
ad alcuni componenti del set di origini main
e modifica
directory root del set di origini 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") ... } } ...
Alla moda
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' ... } } } ...
Tieni presente che una directory di origine può appartenere a un solo set di origini. Ad esempio, non puoi condividere
gli stessi origini di test con entrambi i set di origini test
e androidTest
. Questo
Android Studio crea moduli IntelliJ separati per ogni set di origini e non supporta
le radici dei contenuti duplicati nei set di origine.
Crea con i set di origini
Puoi usare le directory del set di origine per contenere il codice e le risorse che devono essere pacchettizzati solo con determinate configurazioni. Ad esempio, se creando il "demoDebug" una variante di build, che è il prodotto incrociato "demo" versione del prodotto e "debug" tipo di build, Gradle prende in considerazione a queste directory, assegnando loro la seguente priorità:
-
src/demoDebug/
(set di origini delle varianti della build) -
src/debug/
(insieme di origini tipo di build) -
src/demo/
(insieme di origini flavor del prodotto) -
src/main/
(set di origini principali)
I set di origini creati per combinazioni di versioni di prodotto devono includere tutte le dimensioni versioni. Ad esempio, il set di origini delle varianti di build deve essere la combinazione del tipo di build e di tutte le versioni dimensioni. Unione di codice e risorse che coinvolgono cartelle che coprono più risorse ma non tutte le dimensioni versione non sono supportate.
Se combini più prodotti
sapori, la priorità tra i sapori del prodotto è determinata dal sapore
la dimensione a cui appartengono. Quando elenchi le dimensioni delle versioni con i campi
android.flavorDimensions
, le varianti di prodotto
appartengono alla prima dimensione delle versioni che elenchi hanno una priorità maggiore di
quelli appartenenti alla seconda
dimensione Sapore e così via. Inoltre,
gli insiemi di origini che crei per combinazioni di sapori di prodotto hanno un
rispetto agli insiemi di origini che appartengono a una singola versione di prodotto.
L'ordine di priorità determina quale insieme di origini ha un
quando Gradle combina codice e risorse. Poiché demoDebug/
è probabile che la directory del set di origine contenga file specifici di quella build
variante, se demoDebug/
include un file definito anche in
debug/
, Gradle utilizza il file nell'demoDebug/
insieme di origini dati. Allo stesso modo, Gradle fornisce i file per il tipo di build e la versione di prodotto
l'origine imposta una priorità maggiore rispetto agli stessi file in main/
.
Gradle prende in considerazione questo ordine di priorità quando applica le seguenti regole di creazione:
- Tutto il codice sorgente nelle directory
kotlin/
ojava/
viene compilato per generare un singolo output.Nota: per una determinata variante di build, Gradle genera una build un errore se rileva due o più directory del set di origini che hanno definito della stessa classe Kotlin o Java. Ad esempio, quando crei un'app di debug, non puoi definire sia
src/debug/Utility.kt
chesrc/main/Utility.kt
, perché Gradle esamina entrambi queste directory durante il processo di compilazione e genera una "classe duplicata" . Se vuoi versioni diverse diUtility.kt
per diversi tipi di build, ogni tipo deve definire la propria versione del file e non includerlo nel set di originimain/
. - I file manifest vengono uniti in un unico file manifest. La priorità è assegnata nello stesso ordine dell'elenco nell'esempio precedente. Vale a dire, le impostazioni del manifest per una build il tipo sostituisce le impostazioni del file manifest per una versione di prodotto e così via. Per ulteriori informazioni scopri di più sull'unione dei file manifest.
- I file nelle directory
values/
vengono uniti in sinergia. Se due file hanno lo stesso nome, ad esempio duestrings.xml
, la priorità viene assegnata nello stesso ordine dei file nell'esempio precedente. Vale a dire, i valori definiti in un file nel set di origini del tipo di build sostituire i valori definiti nello stesso file in una versione di prodotto e così via. - Risorse nelle directory
res/
easset/
sono pacchettizzati insieme. Se sono presenti risorse con lo stesso nome definito in due o più set di origini, la priorità viene assegnata nello stesso ordine dell'elenco dell'esempio precedente. - Gradle fornisce risorse e manifest inclusi nella libreria alle dipendenze del modulo la priorità più bassa durante la creazione dell'app.
Dichiara le dipendenze
Per configurare una dipendenza per una specifica variante di build
set di origini di test,
inserisci il nome della variante di build o del set di origine di test prima del
Implementation
parola chiave, come illustrato nell'esempio seguente:
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") }
Alla moda
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' }
Per saperne di più sulla configurazione delle dipendenze, consulta Aggiungere dipendenze di build.
Utilizza la gestione delle dipendenze sensibile alle varianti
Il plug-in Android per Gradle 3.0.0 e versioni successive include un nuovo meccanismo di dipendenza che
trova corrispondenze con le varianti quando utilizza una libreria. Significa che la variante debug
di un'app
consuma automaticamente la variante debug
di una raccolta e così via. Funziona anche quando usi
versioni: la variante freeDebug
di un'app utilizzerà l'elemento freeDebug
di una raccolta
e la variante corrispondente.
Affinché il plug-in corrisponda con precisione alle varianti, devi fornire fallback corrispondenti come descritto in nella sezione seguente, per i casi in cui non è possibile una corrispondenza diretta.
Ad esempio, supponiamo che l'app configuri un tipo di build chiamato "temporaneo", ma uno dei al contrario delle sue dipendenze di libreria. Quando il plug-in prova a creare la "temporanea" versione del tuo non saprà quale versione della libreria utilizzare e apparirà un messaggio di errore simile a:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
Risolvere gli errori di build relativi alla corrispondenza delle varianti
Il plug-in include elementi DSL per aiutarti a controllare in che modo Gradle risolve le situazioni non è possibile stabilire una corrispondenza diretta di una variante tra un'app e una dipendenza.
Di seguito è riportato un elenco di problemi relativi alla corrispondenza delle dipendenze in base alle varianti e come utilizzando le proprietà DSL:La tua app include un tipo di build diverso da una dipendenza della libreria.
Ad esempio, la tua app include una "gestione temporanea" un tipo di build, ma una dipendenza include solo "debug" e "release" tipi di build.
Tieni presente che non c'è problema se una dipendenza della libreria include una build che la tua app non sa. Questo perché il plug-in non che generano il tipo di build dalla dipendenza.
Utilizza
matchingFallbacks
per specificare corrispondenze alternative per un determinato tipo di build, come mostrato qui: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") } } }
Alla moda
// 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'] } } }
Per una determinata dimensione flavor presente sia nell'app sia nella relativa raccolta , l'app include versioni non incluse nella libreria.
Ad esempio, sia l'app sia le sue dipendenze di libreria includono un "livello" dimensione sapore. Tuttavia, il "livello" dimensione nell'app include "senza costi" e "a pagamento" sapori, ma la dipendenza include solo "demo" e "a pagamento" sapori per la stessa dimensione.
Tieni presente che, per una determinata dimensione versione esistente sia nell'app sia nella sua raccolta non c'è problema se una libreria include una versione di prodotto che la tua app al contrario. Questo perché il plug-in non richiede mai quel sapore dalla dipendenza.
Usa
matchingFallbacks
per specificare corrispondenze alternative per il termine "senza costi" dell'app versione del prodotto, come mostrato qui: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") } } }
Alla moda
// 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'] } } }
Una dipendenza dalla libreria include una dimensione flavor non inclusa nell'app.
Ad esempio, una dipendenza dalla libreria include versioni per un "minApi" ma la tua app include gusti solo per il "livello" . Quando vuoi creare il debug della versione dell'app, il plug-in non sa se utilizzare o "minApi18Debug" la versione più recente della dipendenza.
Tieni presente che non c'è problema se l'app include una dimensione versione che una raccolta e una dipendenza. Questo perché il plug-in corrisponde solo a versioni delle dimensioni che esiste nella dipendenza. Ad esempio, se una dipendenza non include una dimensione per le ABI, il comando "freeX86Debug" della tua app userebbe "freeDebug" all'ultima versione la dipendenza.
Usa
missingDimensionStrategy
nel bloccodefaultConfig
per specificare la versione predefinita che il plug-in può selezionare tra ogni dimensione mancante, come mostrato nell'esempio riportato di seguito. Puoi anche sostituire le selezioni nelproductFlavors
, in modo che ogni versione possa specificare una strategia di corrispondenza diversa per una dimensione mancante.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") {} } }
Alla moda
// 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 {} } }
Per ulteriori informazioni, visita la pagina matchingFallbacks
.
e missingDimensionStrategy
nel riferimento DSL del plug-in Android Gradle.
Configura le impostazioni di firma
Gradle non firma l'APK o l'AAB della build della release a meno che non definisci esplicitamente un configurazione di firma per questa build. Se non hai ancora una chiave di firma, generare una chiave di caricamento e un archivio chiavi usando Android Studio.
Per configurare manualmente le configurazioni di firma per il tipo di build della release utilizzando le configurazioni di build Gradle:
- Creare un archivio chiavi. Un keystore è un file binario che contiene un set di chiavi private. Devi conservare l'archivio chiavi in un luogo in un luogo sicuro.
- Crea una chiave privata. Per firmare la tua app viene usata una chiave privata per la distribuzione e non sia mai inclusa nell'app o divulgata a terze parti non autorizzate.
-
Aggiungi la configurazione di firma all'elemento
build.gradle.kts
a livello di modulo file:Kotlin
... android { ... defaultConfig {...} signingConfigs { create("release") { storeFile = file("myreleasekey.keystore") storePassword = "password" keyAlias = "MyReleaseKey" keyPassword = "password" } } buildTypes { getByName("release") { ... signingConfig = signingConfigs.getByName("release") } } }
Alla moda
... android { ... defaultConfig {...} signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { ... signingConfig signingConfigs.release } } }
Nota:sono incluse le password per la chiave di rilascio e un archivio chiavi all'interno del file di build non è una buona prassi di sicurezza. Configura invece il file di build in modo da ottenere queste password dalle variabili di ambiente o fare in modo che il processo di compilazione ti chieda di eseguire questi password.
Per ottenere queste password dalle variabili di ambiente:
Kotlin
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
Alla moda
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
In alternativa, puoi caricare l'archivio chiavi da un file delle proprietà locali. Per motivi di sicurezza, non aggiungi questo file al controllo del codice sorgente. Piuttosto, configurali localmente per ogni sviluppatore. Per saperne di più, leggi Rimuovi le informazioni di firma dai file di build.
Al termine della procedura, potrai distribuire e pubblicare la tua app su Google Play.
Avviso: conserva l'archivio chiavi e la chiave privata in un luogo luogo sicuro e di avere copie di backup sicure. Se utilizzi la firma dell'app di Google Play e perdi la chiave di caricamento, puoi richiedi un ripristinarla usando Play Console. Se pubblichi un'app senza la firma dell'app di Google Play (per le app create prima di agosto 2021) e perdi la chiave di firma dell'app, non potrai pubblicare aggiornamenti sull'app, devono sempre firmare tutte le versioni dell'app con la stessa chiave.
Firma delle app per Wear OS
Quando pubblichi app per Wear OS, sia l'APK per orologi sia l'APK facoltativo per smartphone devono essere firmati con il la stessa chiave. Per ulteriori informazioni sulla presentazione e sulla firma delle app per Wear OS, vedi Pacchettizzare e distribuire le app Wear.