Tutorial do Bazel: criar um app Android

Observação: há limitações conhecidas no uso do Bazel para criar apps Android. Acesse a lista de problemas conhecidos na lista de problemas do Android da equipe do GitHub (link em inglês). Embora a equipe do Bazel e os colaboradores de software de código aberto (OSS, na sigla em inglês) trabalhem ativamente para resolver problemas conhecidos, os usuários precisam saber que o Android Studio não oferece suporte oficial a projetos do Bazel.

Este tutorial aborda como criar um app Android simples usando o Bazel.

O Bazel oferece suporte à criação de apps Android usando as regras do Android.

Este tutorial é destinado a usuários do Windows, macOS e Linux e não exige experiência com o Bazel ou o desenvolvimento de apps Android. Não é necessário escrever nenhum código Android neste tutorial.

O que você vai aprender

Neste tutorial, você vai aprender a:

  • Configurar seu ambiente instalando o Bazel e o Android Studio e fazendo o download do projeto de exemplo.
  • Configurar um espaço de trabalho do Bazel que contenha o código-fonte do app e um arquivo MODULE.bazel que identifique o nível superior do diretório do espaço de trabalho.
  • Atualizar o arquivo MODULE.bazel para conter referências às dependências externas necessárias, como o SDK do Android.
  • Criar um arquivo BUILD.
  • Criar o app com o Bazel.
  • Implantar e executar o app em um emulador Android ou dispositivo físico.

Antes de começar

Instalar o Bazel

Antes de começar o tutorial, instale o seguinte software:

  • Bazel. Para instalar, siga as instruções de instalação.
  • Android Studio. Para instalar, siga as etapas para fazer o download do Android Studio. Execute o assistente de configuração para fazer o download do SDK e configurar seu ambiente.
  • (Opcional) Git. Use git para fazer o download do projeto do app Android.

Acessar o projeto de exemplo

Para o projeto de exemplo, use um projeto básico de app Android em no repositório de exemplos do Bazel.

Esse app tem um único botão que imprime uma saudação quando clicado:

Saudação do botão

Figura 1. Saudação do botão do app Android.

Clone o repositório com git (ou faça o download do arquivo ZIP diretamente):

git clone https://github.com/bazelbuild/examples

O projeto de exemplo para este tutorial está em examples/android/tutorial. Para o restante do tutorial, você vai executar comandos nesse diretório.

Analisar os arquivos de origem

Confira os arquivos de origem do app.

.
├── README.md
└── src
    └── main
        ├── AndroidManifest.xml
        └── java
            └── com
                └── example
                    └── bazel
                        ├── AndroidManifest.xml
                        ├── Greeter.java
                        ├── MainActivity.java
                        └── res
                            ├── layout
                            │   └── activity_main.xml
                            └── values
                                ├── colors.xml
                                └── strings.xml

Os principais arquivos e diretórios são:

Nome Local
Arquivos de manifesto do Android src/main/AndroidManifest.xml e src/main/java/com/example/bazel/AndroidManifest.xml
Arquivos de origem do Android src/main/java/com/example/bazel/MainActivity.java e Greeter.java
Diretório de arquivos de recursos src/main/java/com/example/bazel/res/

Criação com o Bazel

Configurar o espaço de trabalho

Um espaço de trabalho é um diretório que contém os arquivos de origem de um ou mais projetos de software e tem um arquivo MODULE.bazel na raiz.

O arquivo MODULE.bazel pode estar vazio ou conter referências a dependências externas necessárias para criar seu projeto.

Primeiro, execute o comando a seguir para criar um arquivo MODULE.bazel vazio:

SO Comando
Linux, macOS touch MODULE.bazel
Windows (prompt de comando) type nul > MODULE.bazel
Windows (PowerShell) New-Item MODULE.bazel -ItemType file

Executar o Bazel

Agora você pode verificar se o Bazel está sendo executado corretamente com o comando:

bazel info workspace

Se o Bazel imprimir o caminho do diretório atual, está tudo certo. Se o MODULE.bazel arquivo não existir, uma mensagem de erro como esta será exibida:

ERROR: The 'info' command is only supported from within a workspace.

Integrar com o SDK do Android

O Bazel precisa executar as ferramentas de build do SDK do Android para criar o app. Isso significa que você precisa adicionar algumas informações ao seu arquivo MODULE.bazel para que o Bazel saiba onde encontrá-las.

Adicione a linha a seguir ao arquivo MODULE.bazel:

bazel_dep(name = "rules_android", version = "0.5.1")

Isso vai usar o SDK do Android no caminho referenciado pela ANDROID_HOME variável de ambiente e detectar automaticamente o nível mais alto da API e a versão mais recente das ferramentas de build instaladas nesse local.

Você pode definir a variável ANDROID_HOME para o local do SDK do Android. Encontre o caminho para o SDK instalado usando o SDK Manager do Android Studio. Supondo que o SDK esteja instalado nos locais padrão, você pode usar os seguintes comandos para definir a variável ANDROID_HOME:

SO Comando
Linux export ANDROID_HOME=$HOME/Android/Sdk/
macOS export ANDROID_HOME=$HOME/Library/Android/sdk
Windows (prompt de comando) set ANDROID_HOME=%LOCALAPPDATA%\Android\Sdk
Windows (PowerShell) $env:ANDROID_HOME="$env:LOCALAPPDATA\Android\Sdk"

Os comandos acima definem a variável apenas para a sessão atual do shell. Para tornar los permanentes, execute os seguintes comandos:

SO Comando
Linux echo "export ANDROID_HOME=$HOME/Android/Sdk/" >> ~/.bashrc
macOS echo "export ANDROID_HOME=$HOME/Library/Android/Sdk/" >> ~/.bashrc
Windows (prompt de comando) setx ANDROID_HOME "%LOCALAPPDATA%\Android\Sdk"
Windows (PowerShell) [System.Environment]::SetEnvironmentVariable('ANDROID_HOME', "$env:LOCALAPPDATA\Android\Sdk", [System.EnvironmentVariableTarget]::User)

Opcional: se você quiser compilar código nativo no seu app Android, também precisará fazer o download do Android NDK e usar rules_android_ndk adicionando a seguinte linha ao arquivo MODULE.bazel:

bazel_dep(name = "rules_android_ndk", version = "0.1.2")

Para mais informações, leia Como usar o Android Native Development Kit com o Bazel.

Não é necessário definir os níveis da API com o mesmo valor para o SDK e o NDK. Esta página contém um mapa de versões do Android para níveis da API com suporte do NDK.

Criar um arquivo BUILD

Um arquivo BUILD descreve a relação entre um conjunto de saídas de build, como recursos compilados do Android de aapt ou arquivos de classe de javac, e as dependências deles. Essas dependências podem ser arquivos de origem (Java, C++) no seu espaço de trabalho ou outras saídas de build. BUILD arquivos são escritos em uma linguagem chamada Starlark.

Os arquivos BUILD fazem parte de um conceito no Bazel conhecido como a hierarquia de pacotes. A hierarquia de pacotes é uma estrutura lógica que sobrepõe a estrutura de diretórios no seu espaço de trabalho. Cada pacote é um diretório (e os subdiretórios dele) que contém um conjunto relacionado de arquivos de origem e um arquivo BUILD. O pacote também inclui todos os subdiretórios, excluindo aqueles que contêm o próprio BUILD arquivo. O nome do pacote é o caminho para o BUILD arquivo em relação ao MODULE.bazel arquivo.

A hierarquia de pacotes do Bazel é conceitualmente diferente da hierarquia de pacotes Java do diretório do app Android em que o arquivo BUILD está localizado, embora os diretórios possam ser organizados de forma idêntica.

Para o app Android simples neste tutorial, os arquivos de origem em src/main/ consistem em um único pacote do Bazel. Um projeto mais complexo pode ter muitos pacotes aninhados.

Adicionar uma regra android_library

Um arquivo BUILD contém vários tipos diferentes de declarações para o Bazel. O tipo mais importante é a regra de build, que informa ao Bazel como criar uma saída de software intermediária ou final de um conjunto de arquivos de origem ou outras dependências. O Bazel oferece duas regras de build, android_library e android_binary, que podem ser usadas para criar um app Android.

Para este tutorial, você vai usar primeiro a regra android_library para informar ao Bazel que crie um módulode biblioteca do Android com o código-fonte do app e os arquivos de recursos. Em seguida, você vai usar a regra android_binary para informar ao Bazel como criar o pacote de aplicativos Android.

Crie um novo arquivo BUILD no diretório src/main/java/com/example/bazel, e declare um novo destino android_library:

src/main/java/com/example/bazel/BUILD:

package(
    default_visibility = ["//src:__subpackages__"],
)

android_library(
    name = "greeter_activity",
    srcs = [
        "Greeter.java",
        "MainActivity.java",
    ],
    manifest = "AndroidManifest.xml",
    resource_files = glob(["res/**"]),
)

A regra de build android_library contém um conjunto de atributos que especificam as informações necessárias para que o Bazel crie um módulo de biblioteca com os arquivos de origem. Observe também que o nome da regra é greeter_activity. Você vai referenciar a regra usando esse nome como uma dependência na regra android_binary.

Adicionar uma regra android_binary

A regra android_binary cria o pacote de aplicativos Android (arquivo .apk) para seu app.

Crie um novo arquivo BUILD no diretório src/main/, e declare um novo destino android_binary:

src/main/BUILD:

android_binary(
    name = "app",
    manifest = "AndroidManifest.xml",
    deps = ["//src/main/java/com/example/bazel:greeter_activity"],
)

Aqui, o deps atributo referencia a saída da greeter_activity regra que você adicionou ao BUILD arquivo acima. Isso significa que, quando o Bazel cria a saída dessa regra, ele verifica primeiro se a saída da greeter_activity regra da biblioteca foi criada e está atualizada. Caso contrário, o Bazel a cria e usa essa saída para criar o arquivo de pacote de aplicativos.

Agora, salve e feche o arquivo.

Criar o app

Tente criar o app. Execute o seguinte comando para criar o android_binary destino:

bazel build //src/main:app

O build subcomando instrui o Bazel a criar o destino que segue. O destino é especificado como o nome de uma regra de build dentro de um arquivo BUILD, com o caminho do pacote relativo ao diretório do espaço de trabalho. Para este exemplo, o destino é app e o caminho do pacote é //src/main/.

Às vezes, é possível omitir o caminho do pacote ou o nome do destino, dependendo de seu diretório de trabalho atual na linha de comando e do nome do destino. Para mais detalhes sobre rótulos e caminhos de destino, consulte Rótulos.

O Bazel vai começar a criar o app de exemplo. Durante o processo de build, a saída será semelhante a esta:

INFO: Analysed target //src/main:app (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //src/main:app up-to-date:
  bazel-bin/src/main/app_deploy.jar
  bazel-bin/src/main/app_unsigned.apk
  bazel-bin/src/main/app.apk

Localizar as saídas de build

O Bazel coloca as saídas de operações de build intermediárias e finais em um conjunto de diretórios de saída por usuário e por espaço de trabalho. Esses diretórios são vinculados simbolicamente dos seguintes locais no nível superior do diretório do projeto, em que o arquivo MODULE.bazel está:

  • bazel-bin armazena executáveis binários e outras saídas de build executáveis.
  • bazel-genfiles armazena arquivos de origem intermediários gerados pelas regras do Bazel.
  • bazel-out armazena outros tipos de saídas de build.

O Bazel armazena o arquivo .apk do Android gerado usando a regra android_binary no diretório bazel-bin/src/main, em que o nome do subdiretório src/main é derivado do nome do pacote do Bazel.

Em um prompt de comando, liste o conteúdo desse diretório e encontre o app.apk arquivo:

SO Comando
Linux, macOS ls bazel-bin/src/main
Windows (prompt de comando) dir bazel-bin\src\main
Windows (PowerShell) ls bazel-bin\src\main

Executar o app

Agora você pode implantar o app em um dispositivo Android conectado ou emulador na linha de comando usando o bazel mobile-install comando. Esse comando usa o Android Debug Bridge (adb) para se comunicar com o dispositivo. Você precisa configurar seu dispositivo para usar adb seguindo as instruções em Android Debug Bridge antes da implantação. Também é possível instalar o app no emulador Android incluído no Android Studio. Verifique se o emulador está em execução antes de executar o comando abaixo.

Digite o seguinte:

bazel mobile-install //src/main:app

Em seguida, encontre e inicie o "Bazel Tutorial App":

App tutorial do Bazel

Figura 2. App de tutorial do Bazel.

Parabéns! Você acabou de instalar seu primeiro app Android criado pelo Bazel.

Observe que o subcomando mobile-install também oferece suporte à flag --incremental que pode ser usada para implantar apenas as partes do app que foram alteradas desde a última implantação.

Ele também oferece suporte à flag --start_app para iniciar o app imediatamente após a instalação.

Leitura adicional

Para mais detalhes, consulte estas páginas:

Divirta-se criando!