Configurar variantes de publicação

As variantes de publicação permitem que você crie uma experiência mais personalizada para os usuários. Com a configuração de variantes de publicação, é possível publicar diferentes variantes de build, cada uma com os próprios atributos.

A publicação de diversas variantes de build da sua biblioteca permite que o usuário escolha os recursos adequados para as necessidades dele. Por exemplo, é possível publicar artefatos diferentes para os tipos de build de depuração e lançamento. O artefato de publicação de depuração pode ter mais códigos de geração de registros e dependências diferentes para ativar esse recurso.

Antes de continuar, prepare sua biblioteca para lançamento.

Usar metadados de módulo do Gradle

Para publicar variantes da sua biblioteca, é preciso usar os metadados do módulo Gradle (GMM, sigla e link em inglês). O GMM descreve sua publicação e mantém o gerenciamento de dependências com reconhecimento de variantes. Por padrão, ele é publicado com sua biblioteca.

Os benefícios de usar o GMM incluem:

  • Se você usa GMMs com Gradle 6.0 ou uma versão mais recente, pode publicar diversas variantes de publicação ou vários artefatos, cada um com os próprios atributos e dependências. Se você usa o arquivo POM (link em inglês) do Maven em vez de GMMs, só é possível publicar um artefato. Se você usa um arquivo POM, pode publicar outros artefatos usando classificadores, mas os artefatos extras não podem ter dependências próprias.
  • O Gradle cria automaticamente uma variante para compilação e outra para o tempo de execução, cada uma com as próprias dependências. É possível publicar uma variante para compilação e outra para execução, de modo que o consumidor possa escolher com base em quando está usando sua biblioteca. O GMM permite que os consumidores vejam dependências diferentes para compilação e execução com base no uso da biblioteca publicada de api, implementation ou compileOnly/runtimeOnly. Consulte Configurações de dependência para uma lista completa de dependências. Essas opções estão disponíveis mesmo quando você publica uma única variante de publicação.
  • Ao usar recursos de teste, você pode publicar uma outra variante com metadados ou recursos especiais que permitam que o consumidor a selecione. Essas opções estão disponíveis mesmo quando você publica uma única variante de publicação.

Entender como as variantes de publicação funcionam

Para entender como as variantes de publicação funcionam, é bom conhecer as etapas básicas de publicação (link em inglês) do Gradle. Confira alguns conceitos importantes sobre a publicação:

  • Variante de build: a configuração que o Gradle usa para criar sua biblioteca, que é o produto cruzado do tipo de build e da variação de produto. Para saber mais, consulte o glossário de build do Android.
  • Artefato (link em inglês): um arquivo ou diretório produzido por um build. No contexto da publicação de bibliotecas, um artefato geralmente é um arquivo JAR ou AAR.
  • Variante de publicação (link em inglês): um artefato com os próprios atributos, recursos e dependências associados. O Gradle chama variantes de publicação apenas de variantes. No entanto, elas são chamadas de variantes de publicação nestes documentos para diferenciá-las das variantes de build.
  • Atributo (link em inglês): o Gradle usa atributos para identificar e selecionar variantes de publicação quando há várias opções. Por exemplo, org.gradle.usage=java-api e org.gradle.jvm.version=11 são atributos de variante.
  • Componente de software (link em inglês): um objeto do Gradle que pode conter uma ou mais variantes de publicação e é publicado em um único conjunto de coordenadas do Maven (groupdId:artifactId:version). Ele é exposto na DSL do Gradle pelo Project.getComponents().
  • Publicação (link em inglês): o que é publicado no repositório e usado pelos consumidores. As publicações consistem em um componente de software e nos metadados dele. Por exemplo, a identidade (groupId:artifactId:version).

O Plug-in do Android para Gradle (AGP) 7.1 introduz uma linguagem específica de domínio (DSL) para controlar quais variantes de build são usadas durante a publicação e quais são ignoradas. A DSL permite criar instâncias de SoftwareComponent que contêm um destes itens:

  • Uma variante de publicação de uma variante de build
  • Diversas variantes de publicação de diversas variantes de build

Ao criar um componente de software com diversas variantes de publicação, o AGP configura atributos em cada variante para que o consumidor possa selecionar a variante de que precisa. Esses atributos vêm diretamente do tipo e das variações de build usados para criar a variante de build. A criação de um componente com uma única variante de publicação não exige atributos porque não é necessário distinguir.

Criar um componente de software com uma única variante de publicação

O snippet abaixo configura um componente de software com uma única variante de publicação criada com a variante de build release, adicionando o JAR de origem como um artefato secundário:

Kotlin

android {
  publishing {
    singleVariant("release") {
        withSourcesJar()
    }
  }
}

Groovy

android {
  publishing {
    singleVariant('release') {
        withSourcesJar()
    }
  }
}

É possível criar vários componentes, cada um com uma única variante de publicação, e distribuí-los em diferentes coordenadas do Maven. Nesse caso, os atributos não são definidos na variante de publicação. Não é possível identificar que essa variante de publicação é da variante de build release analisando os metadados da publicação. Como há apenas uma variante de publicação envolvida, não é necessário desambiguação.

Criar um componente de software com diversas variantes de publicação

Você pode selecionar todas ou um subconjunto de variantes de build para colocar em um único componente de software. O AGP usa automaticamente os nomes de tipo de build, nomes de variação de produto e dimensão de variações para criar atributos. Assim, o projeto consumidor pode distinguir entre eles.

Para publicar todas as variantes de build em um único componente, especifique allVariants() no bloco multipleVariants{} no arquivo build.gradle do módulo:

Kotlin

android {
  publishing {
    multipleVariants {
      allVariants()
      withJavadocJar()
    }
  }
}

Groovy

android {
  publishing {
    multipleVariants {
      allVariants()
      withJavadocJar()
    }
  }
}

Isso cria um único componente chamado default. Para dar outro nome ao componente, use multipleVariants({name}). Nesse caso, todas as dimensões de tipo de build e de variação de produto são usadas como atributos.

Também é possível selecionar quais variantes foram publicadas usando includeBuildTypeValues() e includeFlavorDimensionAndValues():

Kotlin

android {
  publishing {
    multipleVariants("custom") {
      includeBuildTypeValues("debug", "release")
      includeFlavorDimensionAndValues(
        dimension = "color",
        values = arrayOf("blue", "pink")
      )
        includeFlavorDimensionAndValues(
          dimension = "shape",
          values = arrayOf("square")
      )
    }
  }
}

Groovy

android {
  publishing {
    multipleVariants('custom') {
      includeBuildTypeValues('debug', 'release')
      includeFlavorDimensionAndValues(
        /*dimension =*/ 'color',
        /*values =*/ 'blue', 'pink'
      )
      includeFlavorDimensionAndValues(
        /*dimension =*/ 'shape',
        /*values =*/ 'square'
      )
    }
  }
}

Nesse exemplo, o componente personalizado contém todas as combinações de (debug, release) para o tipo de build, (blue, pink) para a dimensão color e (square) para a dimensão shape.

Todas as dimensões de variações precisam ser listadas, mesmo que você esteja publicando apenas um valor de uma dimensão, para que o AGP saiba qual valor usar para cada dimensão.

A tabela abaixo lista as variantes de publicação resultantes e os atributos associados a elas.

Variante Atributos
blueSquareDebug com.android.build.api.attributes.BuildTypeAttr="debug" com.android.build.api.attributes.ProductFlavorAttr:color="blue"
blueSquareRelease com.android.build.api.attributes.BuildTypeAttr="release"
com.android.build.api.attributes.ProductFlavorAttr:color="blue"
pinkSquareDebug com.android.build.api.attributes.BuildTypeAttr="debug"
com.android.build.api.attributes.ProductFlavorAttr:color="pink"
pinkSquareRelease com.android.build.api.attributes.BuildTypeAttr="release"
com.android.build.api.attributes.ProductFlavorAttr:color="pink"

Na prática, mais variantes são publicadas. Por exemplo, cada uma das variantes acima é publicada duas vezes, uma para a compilação e outra para execução, com dependências diferentes (com base no fato de as dependências declaradas usarem implementation ou api) e um valor diferente para o atributo org.gradle.Usage. No entanto, os artefatos (arquivo AAR) dessas duas variantes são os mesmos.

Para saber mais, consulte a documentação da API publishing.

Problema de compatibilidade para publicação de bibliotecas com diversas variações

Um projeto que usa o AGP 7.0 ou versões anteriores não pode consumir bibliotecas com diversas variações publicadas com o AGP 7.1 ou versões mais recentes. Esse é um problema conhecido causado por uma mudança no nome do atributo da dimensão de variação de produto de dimensionName para com.android.build.api.attributes.ProductFlavor:dimensionName no AGP 7.1. Dependendo da configuração do projeto, use missingDimensionStrategy na API da variante antiga para solucionar esse problema.

Por exemplo, suponha que o projeto do aplicativo tenha apenas uma dimensão de variação de produto de versão:

Kotlin

android {
    applicationVariants.forEach { variant ->
        val flavor = variant.productFlavors[0].name
        val attributePrefix = "com.android.build.api.attributes.ProductFlavor"
        val dimensionName = "version"
        variant.missingDimensionStrategy("$attributePrefix:$dimensionName", flavor)
    }
}

Groovy

android {
    applicationVariants.forEach { variant ->
        def flavor = variant.getProductFlavors()[0].name
        def attributePrefix = "com.android.build.api.attributes.ProductFlavor"
        def dimensionName = "version"
        variant.missingDimensionStrategy("$attributePrefix:$dimensionName", flavor)
    }
}