Configura varianti della build

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 altro versionCode. 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:

  1. Fai clic su Gradle nella barra della finestra degli strumenti.
  2. 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:

    1. Fai clic su File > Impostazioni > Sperimentale (Android Studio > Impostazioni > Sperimentale su macOS).
    2. Deseleziona Non consentire creare l'elenco di attività Gradle durante la sincronizzazione Gradle.
  3. 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:

  1. Apri il riquadro Progetto e seleziona Vista Progetto dal menu nella parte superiore del riquadro.
  2. Vai a MyProject/app/src/.
  3. Fai clic con il tasto destro del mouse sulla directory src e seleziona Nuovo > Directory.
  4. Dal menu in Set di origini di Gradle, seleziona full/java.
  5. 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:

  1. Nel riquadro Progetto, fai clic con il pulsante destro del mouse sull'src directory e seleziona Nuovo > XML > File XML dei valori.
  2. Inserisci il nome del file XML o mantieni il nome predefinito.
  3. Nel menu accanto a Set di origini target, seleziona debug.
  4. 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.

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à:

  1. src/demoDebug/ (set di origini delle varianti della build)
  2. src/debug/ (insieme di origini tipo di build)
  3. src/demo/ (insieme di origini flavor del prodotto)
  4. 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/ o java/ 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 che src/main/Utility.kt, perché Gradle esamina entrambi queste directory durante il processo di compilazione e genera una "classe duplicata" . Se vuoi versioni diverse di Utility.kt per diversi tipi di build, ogni tipo deve definire la propria versione del file e non includerlo nel set di origini main/.

  • 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 due strings.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/ e asset/ 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 blocco defaultConfig 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 nel productFlavors , 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:

  1. 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.
  2. 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.
  3. 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.