Visão geral do build do Gradle

Os apps Android geralmente são criados usando o build do Gradle. sistema. Antes de nos aprofundarmos em como configurar seu build, vamos explorar os conceitos por trás do build para que você possa ver o sistema como um todo.

O que é uma versão?

Um sistema de build transforma seu código-fonte em um aplicativo executável. Os builds geralmente envolvem várias ferramentas para analisar, compilar, vincular e empacotar seus aplicativo ou biblioteca. O Gradle usa uma abordagem baseada em tarefas para organizar e executar esses comandos.

Tasks encapsulam comandos que traduzem suas entradas em de entrada e saída. Os plug-ins definem as tarefas e as configurações delas. Aplicando Um plug-in do build registra as tarefas e as conecta usando as entradas e saídas. Por exemplo, aplicar o Plug-in do Android para Gradle (AGP). ao seu arquivo de compilação registrará todas as tarefas necessárias para compilar um APK ou um Biblioteca do Android. O plug-in java-library permite criar um jar usando a origem Java. o código-fonte é alterado. Existem plug-ins semelhantes para o Kotlin e outras linguagens, mas há outros plug-ins têm como objetivo ampliar os plug-ins. Por exemplo, o plug-in protobuf serve para adicionar Suporte a protobuf para plug-ins existentes, como AGP ou java-library.

O Gradle prefere usar convenções em vez de configurações, então os plug-ins terão boas valores padrão prontos para uso, mas é possível configurar ainda mais o build por meio de uma declarativa, com uma linguagem específica de domínio (DSL, na sigla em inglês). A DSL foi projetada Você pode especificar o que criar, em vez de como fazer isso. A lógica os plug-ins gerenciam o "como". Essa configuração é especificada em várias arquivos de build no seu projeto (e subprojetos).

As entradas de tarefas podem ser arquivos e diretórios, bem como outras informações codificadas como Tipos Java (número inteiro, strings ou classes personalizadas). As saídas só podem ser de diretório ou arquivos, porque eles precisam ser gravados em disco. Conectar a saída de uma tarefa a outra entrada de tarefa, vincula as tarefas para que uma tenha que ser executada antes da outra.

Embora o Gradle ofereça suporte à criação de declarações de código arbitrário e tarefas no seu build, Isso pode dificultar o entendimento do build e da para você manter. Por exemplo, é possível programar testes de código dentro de plug-ins mas não nos arquivos de build. Em vez disso, você deve restringir a lógica de build e as tarefas declarações a plug-ins (que você ou outra pessoa define) e declaram como usar essa lógica nos arquivos de build.

O que acontece quando um build do Gradle é executado?

Os builds do Gradle são executados em três fases. Cada uma dessas fases executa diferentes partes de código definidos nos arquivos de build.

  • A inicialização determina quais projetos e subprojetos são incluídos. a compilação e define caminhos de classe que contêm os arquivos de compilação e os plug-ins. Essa fase se concentra em um arquivo de configurações em que você declara projetos para build e os locais de onde buscar plug-ins e bibliotecas.
  • Configuração registra tarefas para cada projeto e executa o build para aplicar a especificação de compilação do usuário. É importante entender para que o código de configuração não tenha acesso aos dados ou arquivos durante a execução.
  • A execução realiza a "criação" real. do seu aplicativo. O resultado de configuração é um gráfico acíclico dirigido (DAG, na sigla em inglês) de tarefas, que representam todas as etapas de compilação necessárias que foram solicitadas pelo usuário (o tarefas fornecidas na linha de comando ou como padrões nos arquivos de build). Isso gráfico representa a relação entre tarefas, seja explícita no nível ou com base nas entradas e saídas dele. Se uma tarefa tem uma entrada que for a saída de outra tarefa, ele deverá ser executado após a outra tarefa. Isso a fase executa tarefas desatualizadas na ordem definida no gráfico; se uma tarefa entradas não tiverem mudado desde a última execução, o Gradle a ignorará.

Para saber mais, consulte o Ciclo de vida do build do Gradle.

DSLs de configuração

O Gradle usa uma linguagem específica de domínio (DSL) para configurar builds. Essa abordagem declarativa se concentra na especificação dos dados, escrevendo instruções (imperativas) passo a passo.

As DSLs tentam facilitar para todos, especialistas no domínio e programadores, contribuir para um projeto, definindo uma linguagem pequena que representa os dados em uma de forma mais natural. Os plug-ins do Gradle podem estender a DSL para configurar os dados que eles precisam para as tarefas.

Por exemplo, a configuração da parte Android do seu build pode ser semelhante a esta:

Kotlin

android {
    namespace = "com.example.app"
    compileSdk = 34
    // ...

    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 34
        // ...
    }
}

Groovy

android {
    namespace 'com.example.myapplication'
    compileSdk 34
    // ...

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdk 24
        // ...
    }
}

Internamente, o código DSL é semelhante a:

fun Project.android(configure: ApplicationExtension.() -> Unit) {
    ...
}

interface ApplicationExtension {
    var compileSdk: Int
    var namespace: String?

    val defaultConfig: DefaultConfig

    fun defaultConfig(configure: DefaultConfig.() -> Unit) {
        ...
    }
}

Cada bloco na DSL é representado por uma função que usa um lambda para configurá-lo e uma propriedade com o mesmo nome para acessá-lo. Isso faz nos arquivos de build parecem mais uma especificação de dados.

Dependências externas

O sistema de build Maven introduziu uma especificação de dependência, em um sistema de armazenamento e gerenciamento. As bibliotecas são armazenadas em repositórios (servidores ou diretórios), com metadados, incluindo a versão e as dependências delas em outras bibliotecas. Você especifica qual repositórios para pesquisar, versões das dependências que você quer usar e as o sistema de build faz o download deles durante o build.

Os artefatos do Maven são identificados por nome de grupo (empresa, desenvolvedor etc.), artefato (o nome da biblioteca) e a versão desse artefato. Isso normalmente ocorre representado como group:artifact:version.

Essa abordagem melhora significativamente o gerenciamento de builds. Você ouvirá essas repositórios chamados "repositórios Maven", mas se trata da maneira os artefatos são empacotados e publicados. Esses repositórios e metadados foram reutilizado em vários sistemas de build, incluindo o Gradle (e o Gradle pode publicar em esses repositórios. Os repositórios públicos permitem o compartilhamento para todos usarem e os repositórios da empresa mantêm as dependências internas internamente.

Também é possível modularizar o projeto em subprojetos. (também conhecidos como "módulos" no Android Studio), que também podem ser usados como dependências. Cada subprojeto produz saídas (como jars) que podem ser consumida por subprojetos ou pelo seu projeto de nível superior. Isso pode melhorar o tempo de build isolando quais peças precisam ser reconstruídas, assim como separar melhor responsabilidades de segurança no aplicativo.

Entraremos em mais detalhes sobre como especificar dependências em Adicionar dependências.

Variantes de build

Ao criar um aplicativo Android, você provavelmente vai querer criar vários variantes. As variantes têm códigos diferentes ou são criadas com e são compostos de tipos de build e variações de produto.

Os tipos de build variam as opções de build declaradas. Por padrão, o AGP configura "versão" e "debug" tipos de build, mas é possível ajustá-los e adicionar mais (talvez para ou testes internos).

Um build de depuração não reduz nem ofusca seu aplicativo, acelerando a criar e preservar todos os símbolos no estado em que se encontram. Isso também marca o aplicativo como "depurável", assinando-o com uma chave de depuração genérica e permitindo o acesso ao os arquivos de aplicativos instalados no dispositivo. Isso possibilita explorar dados salvos em arquivos e bancos de dados durante a execução do aplicativo.

Um build de lançamento otimiza o aplicativo, o assina com sua chave de lançamento e protege os arquivos dos aplicativos instalados.

Usando variações de produto, é possível alterar a origem e a dependência incluídas variantes para o aplicativo. Por exemplo, crie "demonstração" e "cheio" variações para seu aplicativo, ou talvez "sem custo financeiro", e "paga" aromatizantes. Você escreve sua fonte comum em um "principal" diretório source set, e substituir ou adicionar origem em um conjunto de origem com o nome da variação.

O AGP cria variantes para cada combinação de tipo de build e variação de produto. Se você não definir variações, elas serão nomeadas de acordo com os tipos de build. Se você definir ambos, a variante será denominada <flavor><Buildtype>. Por exemplo, com o build tipos release e debug e as variações demo e full, o AGP cria variantes:

  • demoRelease
  • demoDebug
  • fullRelease
  • fullDebug

Próximas etapas

Agora que você já conhece os conceitos de build, confira a página de criação do Android estrutural em seu projeto.