The Android Developer Challenge is back! Submit your idea before December 2.

Configurar sua compilação

O sistema de compilação do Android compila os recursos e o código-fonte do app e os empacota em APKs que você pode testar, implantar, assinar e distribuir.

O sistema de compilação do Android compila os recursos e o código-fonte do app e os empacota em APKs que você pode testar, implantar, assinar e distribuir. O Android Studio usa o Gradle, um kit de ferramentas de compilação avançado, para automatizar e gerenciar o processo de compilação, permitindo que você defina configurações de compilação personalizadas e flexíveis. Cada configuração de compilação pode definir o próprio conjunto de códigos e recursos, reutilizando as partes comuns a todas as versões do app. O plug-in do Android para Gradle funciona com o kit de ferramentas de compilação para oferecer processos e configurações ajustáveis específicas para compilar e testar aplicativos Android.

O Gradle e o plug-in do Android são executados de forma independente do Android Studio. Isso significa que você pode compilar seus apps Android pelo Android Studio, pela linha de comando do seu computador ou em computadores em que o Android Studio não esteja instalado (como servidores de integração contínua). Se você não estiver usando o Android Studio, veja como compilar e executar seu app pela linha de comando. A saída da compilação é a mesma, esteja você compilando o projeto em uma linha de comando, em um computador remoto ou usando o Android Studio.

Observação: como o Gradle e o plug-in do Android são executados de forma independente do Android Studio, é necessário atualizar as ferramentas de compilação separadamente. Leia as notas da versão para saber como atualizar o Gradle e o plug-in do Android.

A flexibilidade do sistema de compilação do Android permite realizar configurações de compilação personalizadas sem modificar os arquivos dos recursos principais do app. Esta seção ajuda a entender como o sistema de compilação do Android funciona e como ele pode ajudar a personalizar e automatizar várias configurações de compilação. Se quiser saber mais sobre como implantar seu app, consulte Programar e executar no Android Studio. Para começar a criar configurações de compilação personalizadas imediatamente usando o Android Studio, consulte Configurar variantes de compilação.

O processo de compilação

O processo de compilação envolve muitas ferramentas e processos que convertem seu projeto em um Pacote de Aplicativo Android (APK, na sigla em inglês). Como esse processo é bastante flexível, é útil entender como ele funciona.

Figura 1. Processo de compilação de um módulo típico de app Android.

O processo de compilação de um módulo típico de app Android, conforme é mostrado na figura 1, segue as seguintes etapas gerais:

  1. Os compiladores convertem seu código-fonte em arquivos DEX (Dalvik Executable), que incluem o bytecode que é executado em dispositivos Android e todo o restante em recursos compilados.
  2. O APK Packager combina os arquivos DEX e os recursos compilados em um único APK. No entanto, para que seu app possa ser instalado e implantado em um dispositivo Android, o APK precisa ser assinado.
  3. O APK Packager assina o APK usando o repositório de chaves de lançamento ou de depuração:
    1. Se você estiver compilando uma versão de depuração do seu app, ou seja, um app apenas para teste e geração de perfis, o Packager o assinará com o repositório de chaves de depuração. O Android Studio configura novos projetos automaticamente com um repositório de chaves de depuração.
    2. Se você estiver compilando uma versão de lançamento do app que pretende lançar externamente, o Packager o assinará usando o repositório de chaves de lançamento. Para criar um repositório de chaves de lançamento, veja como assinar seu app no Android Studio.
  4. Antes de gerar seu APK final, o Packager usa a ferramenta zipalign para otimizar seu app para usar menos memória quando ele for executado em um dispositivo.

No final do processo de compilação, você tem um APK de depuração ou de lançamento que pode ser usando para implantar, testar ou lançar o app para usuários externos.

Configurações de compilação personalizadas

O Gradle e o plug-in do Android ajudam a configurar os seguintes aspectos da sua compilação:

Tipos de compilação
Os tipos de compilação definem certas propriedades que o Gradle usa ao compilar e empacotar seu app. Geralmente, eles são configurados para diferentes fases do seu ciclo de desenvolvimento. Por exemplo, o tipo de compilação de depuração oferece opções de depuração e assina o APK com a chave de depuração, enquanto o tipo de compilação de lançamento pode reduzir, ofuscar e assinar seu APK com uma chave de lançamento para distribuição. É necessário definir pelo menos um tipo de compilação para compilar seu app. Por padrão, o Android Studio cria os tipos de compilação de depuração e de lançamento. Para começar a personalizar as configurações de empacotamento do app, veja como Configurar tipos de compilação.
Variações de produtos
As variações de produtos representam diferentes versões do seu app que você pode lançar para os usuários, por exemplo, versões gratuita e paga do app. Você pode compartilhar e reutilizar partes comuns a todas as versões do app para personalizar variações de produtos para usar diferentes códigos e recursos As variações de produtos são opcionais e precisam ser criadas manualmente. Para começar a criar diferentes versões do app, veja como Configurar variações de produtos.
Variantes de compilação
As variantes de compilação são vários produtos de um tipo de compilação e uma variação de produto. Essa é a configuração que o Gradle usa para compilar seu app. Com as variantes de compilação, é possível compilar a versão de depuração das suas variações de produtos durante o desenvolvimento ou versões de lançamento assinadas das variações de produtos para distribuição. Apesar de não ser necessário configurar as variantes de compilação diretamente, é preciso configurar os tipos de compilação e as variações de produtos que as compõem. A criação de outros tipos de compilação ou variações de produtos também faz com que outras variantes de compilação sejam criadas. Para saber como criar e gerenciar variantes de compilação, leia a visão geral de como Configurar variantes de compilação.
Entradas do manifesto
Você pode especificar valores para algumas propriedades do arquivo de manifesto na configuração da variante de compilação. Esses valores de compilação modificam os valores existentes no arquivo de manifesto. Isso é útil se você quer gerar vários APKs para seus módulos, com cada arquivo .apk tendo valores diferentes para nome do aplicativo, versão mínima do SDK ou versão de destino do SDK. Quando há vários manifestos, o Gradle combina as configurações de manifesto.
Dependências
O sistema de compilação gerencia as dependências do projeto por meio de seu sistema de arquivos local e de repositórios remotos. Isso evita a necessidade de pesquisar, fazer o download e copiar manualmente os pacotes binários das suas dependências para o diretório do projeto. Para saber mais, consulte Adicionar dependências de compilação.
Assinaturas
O sistema de compilação permite especificar configurações de assinatura nas definições da compilação e pode assinar seus APKs automaticamente durante o processo de compilação. O sistema assina a versão de depuração com uma chave e um certificado padrão, usando credenciais conhecidas para evitar solicitações de senha no momento da compilação. O sistema não assina a versão de lançamento a menos que você defina explicitamente uma configuração de assinatura para essa compilação. Se você não tem chave de lançamento, pode gerar uma conforme a descrição apresentada em Assinar o app.
ProGuard
O sistema de compilação permite especificar um arquivo de regras do ProGuard diferente para cada variante de compilação. O sistema pode executar o ProGuard para reduzir e ofuscar suas classes durante o processo de compilação.
Compatibilidade com vários APKs
O sistema de compilação permite compilar automaticamente diferentes APKs, cada um contendo apenas os códigos e recursos necessários para uma densidade de tela ou interface binária de aplicativo (ABI, na sigla em inglês) específica. Para saber mais, consulte Compilar vários APKs.

Arquivos de configuração de compilação

Para criar configurações de compilação personalizadas, você precisa alterar um ou mais arquivos de configuração de compilação, ou arquivos build.gradle. Esses arquivos de texto simples usam a Domain Specific Language (DSL) para descrever e manipular a lógica de compilação que usa Groovy, que é uma linguagem dinâmica para a Java Virtual Machine (JVM). Não é preciso conhecer Groovy para começar a configurar sua compilação porque o plug-in do Android para Gradle introduz a maioria dos elementos DSL necessários. Para saber mais sobre a DSL do plug-in do Android, leia a documentação de referência de DSL.

Ao iniciar um novo projeto, o Android Studio cria automaticamente alguns desses arquivos para você, conforme é mostrado na figura 2, e os preenche com base em padrões razoáveis.

Figura 2. Estrutura de projeto padrão de um módulo de app Android.

Existem alguns arquivos de configuração de compilação do Gradle que fazem parte da estrutura de projeto padrão de um app Android. Antes de começar a configurar sua compilação, é importante entender o escopo e o propósito de cada um desses arquivos e os elementos DSL que eles devem definir.

Arquivo de configurações do Gradle

O arquivo settings.gradle, localizado no diretório raiz do projeto, informa ao Gradle quais módulos ele deve incluir ao compilar seu app. Para a maioria dos projetos, o arquivo é simples e inclui apenas o seguinte:

    include ‘:app’
    

Entretanto, projetos com vários módulos precisam especificar cada módulo a ser incluído na compilação final.

Arquivo de compilação de nível mais alto

O arquivo build.gradle de nível mais alto, localizado no diretório raiz do projeto, define configurações de compilação que se aplicam a todos os módulos do seu projeto. Por padrão, o arquivo de compilação de nível mais alto usa o bloco buildscript para definir os repositórios e as dependências do Gradle que são comuns a todos os módulos do projeto. O exemplo de código a seguir descreve as configurações padrão e os elementos de DSL encontrados no arquivo build.gradle de nível mais alto após a criação de um novo projeto.

    /**
     * The buildscript block is where you configure the repositories and
     * dependencies for Gradle itself—meaning, you should not include dependencies
     * for your modules here. For example, this block includes the Android plugin for
     * Gradle as a dependency because it provides the additional instructions Gradle
     * needs to build Android app modules.
     */

    buildscript {

        /**
         * The repositories block configures the repositories Gradle uses to
         * search or download the dependencies. Gradle pre-configures support for remote
         * repositories such as JCenter, Maven Central, and Ivy. You can also use local
         * repositories or define your own remote repositories. The code below defines
         * JCenter as the repository Gradle should use to look for its dependencies.
         *
         * New projects created using Android Studio 3.0 and higher also include
         * Google's Maven repository.
         */

        repositories {
            google()
            jcenter()
        }

        /**
         * The dependencies block configures the dependencies Gradle needs to use
         * to build your project. The following line adds Android plugin for Gradle
         * version 3.4.2 as a classpath dependency.
         */

        dependencies {
            classpath 'com.android.tools.build:gradle:3.4.2'
        }
    }

    /**
     * The allprojects block is where you configure the repositories and
     * dependencies used by all modules in your project, such as third-party plugins
     * or libraries. However, you should configure module-specific dependencies in
     * each module-level build.gradle file. For new projects, Android Studio
     * includes JCenter and Google's Maven repository by default, but it does not
     * configure any dependencies (unless you select a template that requires some).
     */

    allprojects {
       repositories {
           google()
           jcenter()
       }
    }
    

Configurar propriedades para todo o projeto

Para projetos do Android que incluem diversos módulos, pode ser útil definir certas propriedades no nível do projeto e compartilhá-las em todos os módulos. É possível fazer isso adicionando propriedades extras ao bloco ext no arquivo build.gradle de nível mais alto.

    buildscript {...}

    allprojects {...}

    // This block encapsulates custom properties and makes them available to all
    // modules in the project.
    ext {
        // The following are only a few examples of the types of properties you can define.
        compileSdkVersion = 28
        // You can also create properties to specify versions for dependencies.
        // Having consistent versions between modules can avoid conflicts with behavior.
        supportLibVersion = "28.0.0"
        ...
    }
    ...
    

Para acessar essas propriedades a partir de um módulo no mesmo projeto, use a seguinte sintaxe no arquivo build.gradle do módulo (saiba mais sobre esse arquivo na seção abaixo).

    android {
      // Use the following syntax to access properties you defined at the project level:
      // rootProject.ext.property_name
      compileSdkVersion rootProject.ext.compileSdkVersion
      ...
    }
    ...
    dependencies {
        implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
        ...
    }
    

Observação: embora o Gradle permita definir as propriedades de todo o projeto no nível do módulo, evite fazer isso, uma vez que essa ação faz com que os módulos que compartilham essas propriedades sejam vinculados. A vinculação do módulo dificulta a exportação posterior de um módulo como projeto independente e impede que o Gradle utilize a execução paralela de projetos para agilizar as compilações que têm vários módulos.

Arquivo de compilação de nível de módulo

O arquivo build.gradle de nível de módulo, localizado em cada diretório project/module/, permite definir configurações de compilação para o módulo específico onde ele se encontra. A definição dessas configurações de compilação permite disponibilizar opções de empacotamento personalizadas, como tipos de compilação e variações de produtos extras, além de modificar as configurações no manifesto de app main/ ou no arquivo build.gradle de nível mais alto.

Este arquivo build.gradle de módulo do exemplo de app Android descreve alguns dos elementos de DSL básicos e das configurações que você precisa conhecer.

    /**
     * The first line in the build configuration applies the Android plugin for
     * Gradle to this build and makes the android block available to specify
     * Android-specific build options.
     */

    apply plugin: 'com.android.application'

    /**
     * The android block is where you configure all your Android-specific
     * build options.
     */

    android {

      /**
       * compileSdkVersion specifies the Android API level Gradle should use to
       * compile your app. This means your app can use the API features included in
       * this API level and lower.
       */

      compileSdkVersion 28

      /**
       * buildToolsVersion specifies the version of the SDK build tools, command-line
       * utilities, and compiler that Gradle should use to build your app. You need to
       * download the build tools using the SDK Manager.
       *
       * This property is optional because the plugin uses a recommended version of
       * the build tools by default.
       */

      buildToolsVersion "29.0.0"

      /**
       * The defaultConfig block encapsulates default settings and entries for all
       * build variants, and can override some attributes in main/AndroidManifest.xml
       * dynamically from the build system. You can configure product flavors to override
       * these values for different versions of your app.
       */

      defaultConfig {

        /**
         * applicationId uniquely identifies the package for publishing.
         * However, your source code should still reference the package name
         * defined by the package attribute in the main/AndroidManifest.xml file.
         */

        applicationId 'com.example.myapp'

        // Defines the minimum API level required to run the app.
        minSdkVersion 15

        // Specifies the API level used to test the app.
        targetSdkVersion 28

        // Defines the version number of your app.
        versionCode 1

        // Defines a user-friendly version name for your app.
        versionName "1.0"
      }

      /**
       * The buildTypes block is where you can configure multiple build types.
       * By default, the build system defines two build types: debug and release. The
       * debug build type is not explicitly shown in the default build configuration,
       * but it includes debugging tools and is signed with the debug key. The release
       * build type applies Proguard settings and is not signed by default.
       */

      buildTypes {

        /**
         * By default, Android Studio configures the release build type to enable code
         * shrinking, using minifyEnabled, and specifies the Proguard settings file.
         */

        release {
            minifyEnabled true // Enables code shrinking for the release build type.
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
      }

      /**
       * The productFlavors block is where you can configure multiple product flavors.
       * This allows you to create different versions of your app that can
       * override the defaultConfig block with their own settings. Product flavors
       * are optional, and the build system does not create them by default.
       *
       * This example creates a free and paid product flavor. Each product flavor
       * then specifies its own application ID, so that they can exist on the Google
       * Play Store, or an Android device, simultaneously.
       *
       * If you declare product flavors, you must also declare flavor dimensions
       * and assign each flavor to a flavor dimension.
       */

      flavorDimensions "tier"
      productFlavors {
        free {
          dimension "tier"
          applicationId 'com.example.myapp.free'
        }

        paid {
          dimension "tier"
          applicationId 'com.example.myapp.paid'
        }
      }

      /**
       * The splits block is where you can configure different APK builds that
       * each contain only code and resources for a supported screen density or
       * ABI. You'll also need to configure your build so that each APK has a
       * different versionCode.
       */

      splits {
        // Settings to build multiple APKs based on screen density.
        density {

          // Enable or disable building multiple APKs.
          enable false

          // Exclude these densities when building multiple APKs.
          exclude "ldpi", "tvdpi", "xxxhdpi", "400dpi", "560dpi"
        }
      }
    }

    /**
     * The dependencies block in the module-level build configuration file
     * specifies dependencies required to build only the module itself.
     * To learn more, go to Add build dependencies.
     */

    dependencies {
        implementation project(":lib")
        implementation 'com.android.support:appcompat-v7:28.0.0'
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    }
    

Arquivos de propriedades do Gradle

O Gradle também contém dois arquivos de propriedades, localizados no diretório raiz do seu projeto, úteis para especificar configurações para o próprio kit de ferramentas de compilação do Gradle:

gradle.properties
Nesse arquivo, é possível definir configurações do Gradle para todo o projeto, como o tamanho máximo de heap do daemon do Gradle. Para saber mais, consulte o Ambiente de compilação.
local.properties
Esse arquivo configura as propriedades de ambiente local do sistema de compilação, como o caminho da instalação do SDK. Como o conteúdo desse arquivo é gerado automaticamente pelo Android Studio e é específico ao ambiente do desenvolvedor local, evite modificá-lo manualmente ou inseri-lo no seu sistema de controle de versões.

Sincronizar o projeto com arquivos do Gradle

Quando você altera os arquivos de configuração de compilação do seu projeto, o Android Studio exige a sincronização dos arquivos para permitir a importação das alterações e a execução de algumas verificações, garantindo que as configurações não criem erros de compilação.

Para sincronizar os arquivos do projeto, clique em Sync Now na barra de notificações exibida ao fazer alterações, conforme é mostrado na figura 3, ou clique em Sync Project na barra de menu. Se o Android Studio perceber erros na sua configuração, por exemplo, se o código-fonte usar recursos de API que só estão disponíveis em um nível de API posterior à sua compileSdkVersion, a janela Messages será exibida com uma descrição do problema.

Figura 3. Sincronização do projeto com arquivos de configuração de compilação no Android Studio.

Conjuntos de origem

O Android Studio agrupa o código-fonte e os recursos de maneira lógica para cada módulo, criando conjuntos de origem. O conjunto de origem main/ de um módulo contém os códigos e os recursos usados por todas as variantes de compilação dele. Outros diretórios de conjuntos de origem são opcionais, e o Android Studio não os cria automaticamente quando você configura novas variantes de compilação. Entretanto, a criação de conjuntos de origem, semelhante ao main/, ajuda a organizar os arquivos e recursos que o Gradle só deve usar ao compilar certas versões do app:

src/main/
Esse conjunto de origem inclui os códigos e recursos comuns a todas as variantes de compilação.
src/buildType/
Crie esse conjunto de origem para incluir os códigos e recursos exclusivos de um tipo de compilação específico.
src/productFlavor/
Crie esse conjunto de origem para incluir os códigos e recursos exclusivos de uma variação específica de produto.

Observação: se você configurar sua compilação para combinar diversas variações de produtos, poderá criar diretórios de conjuntos de origem para cada combinação de variações de produtos entre as dimensões de variações: src/productFlavor1ProductFlavor2/

src/productFlavorBuildType/
Crie esse conjunto de origem para incluir os códigos e recursos exclusivos de uma variante de compilação específica.

Por exemplo, para gerar a versão "fullDebug" do app, o sistema de compilação combina códigos, configurações e recursos dos seguintes conjuntos de origem:

  • src/fullDebug/ (conjunto de origem da variante de compilação)
  • src/debug/ (conjunto de origem do tipo de compilação)
  • src/full/ (conjunto de origem da variação de produtos)
  • src/main/ (conjunto de origem principal)

Observação: ao criar um novo arquivo ou diretório no Android Studio usando as opções de menu File > New, você pode criá-lo para um conjunto de origem específico. Os conjuntos de origem disponíveis para escolha se baseiam nas suas configurações de compilação, e o Android Studio cria os diretórios necessários automaticamente caso eles ainda não existam.

Se conjuntos de origem diferentes contiverem outras versões do mesmo arquivo, o Gradle usará a seguinte ordem de prioridade para decidir qual arquivo usar (os conjuntos de origem à esquerda modificam os arquivos e as configurações dos conjuntos de origem à direita):

variação de compilação > tipo de compilação > variação de produtos > conjunto de origem principal > dependências de biblioteca

Isso permite que o Gradle use arquivos específicos à variante de compilação que você está tentando compilar reutilizando atividades, lógica de aplicativo e recursos comuns a outras versões do seu app. Ao combinar vários manifestos, o Gradle usa a mesma ordem de prioridade, portanto, cada variante de compilação pode definir diferentes componentes ou permissões no manifesto final. Para saber mais sobre como criar conjuntos de origem personalizadas, acesse Criar conjuntos de origem para variantes de compilação.