O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

d8

d8 é uma ferramenta de linha de comando que o Android Studio e o Plug-in do Android para Gradle usam para compilar o bytecode Java do seu projeto no bytecode DEX executado em dispositivos Android. Ele permite usar recursos da linguagem Java 8 no código do seu app.

d8 também está incluído como uma ferramenta autônoma nas Android Build Tools 28.0.1 e mais recentes do Android: android_sdk/build-tools/version/.

Uso geral

d8 é simples de usar e requer apenas um caminho para o bytecode Java compilado que você quer converter em bytecode DEX, conforme mostrado abaixo.

d8 MyProject/app/build/intermediates/classes/debug/*/*.class

O bytecode de entrada pode estar em qualquer combinação de arquivos *.class ou contêineres, como arquivos JAR, APK ou ZIP. Você também pode incluir arquivos DEX para que d8 mescle esses arquivos na saída DEX, o que é útil ao incluir a saída de um build incremental.

Por padrão, d8 compila o bytecode Java em arquivos DEX otimizados e inclui informações de depuração que podem ser usadas para depurar seu código durante o tempo de execução. No entanto, você pode incluir sinalizações opcionais para, por exemplo, executar um build incremental, especificar classes que precisam ser compiladas no arquivo DEX principal e especificar caminhos para recursos adicionais necessários para uso de recursos da linguagem Java 8.

d8 path-to-input-files [options]

A tabela a seguir descreve as sinalizações opcionais que você pode usar com d8.

Opção Descrição
--debug Compila o bytecode DEX incluindo informações de depuração, como tabelas de símbolos de depuração.

Esta opção é ativada por padrão. Para incluir informações de depuração no bytecode DEX, o d8 espera que o bytecode Java de entrada contenha essas informações. Por exemplo, se você estiver usando javac para compilar seu código, será necessário transmitir a sinalização -g para incluir informações de depuração no bytecode Java de saída.

Ao compilar arquivos DEX para a versão de lançamento do seu app ou biblioteca, use a sinalização --release descrita abaixo.

--release Compila o bytecode DEX sem informações de depuração. No entanto, d8 inclui algumas informações usadas ao gerar rastreamentos de pilha e exceções de registros.

Transmita essa sinalização ao compilar bytecode para uma versão pública.

--output path Especifica o caminho desejado para a saída DEX. Por padrão, d8 gera o(s) arquivo(s) DEX no diretório de trabalho atual.

Se você especificar um caminho e o nome de um arquivo ZIP ou JAR, d8 criará o arquivo especificado e incluirá os arquivos DEX de saída. Se você especificar o caminho para um diretório existente, d8 gerará os arquivos DEX nesse diretório.

--lib android_sdk/platforms/api-level/android.jar Especifica o caminho para android.jar do SDK do Android. Essa sinalização é necessária ao compilar bytecodes que usam recursos da linguagem Java 8.
--classpath path Especifica os recursos do caminho de classe necessários para que d8 compile os arquivos DEX do seu projeto. Em particular, d8 requer a especificação de determinados recursos ao compilar bytecodes que usam recursos da linguagem Java 8.
--min-api number Especifica o nível mínimo de API com o qual você quer que os arquivos DEX de saída sejam compatíveis.
--intermediate Transmita essa sinalização para informar d8 que você não está compilando o conjunto completo de bytecode Java do projeto. Essa sinalização é útil ao executar builds incrementais: ao invés e compilar arquivos DEX otimizados que você espera executar em um dispositivo, d8 cria arquivos DEX intermediários e armazena-os na saída especificada ou no caminho padrão.

Quando quiser compilar arquivos DEX que você pretende executar em um dispositivo, exclua essa sinalização e especifique o caminho para as classes DEX intermediárias como entrada.

--file-per-class Compila cada classe em um arquivo DEX diferente.

A ativação dessa sinalização permite que você execute mais builds incrementais, recompilando apenas as classes que mudaram. Ao executar builds incrementais usando o Plug-in do Android para Gradle, essa otimização é ativada por padrão.

Não é possível usar essa sinalização ao especificar --main-dex-list.

--no-desugaring Desativa os recursos da linguagem Java 8. Use essa sinalização apenas se você não pretende compilar bytecode Java que usa recursos da linguagem Java 8.
--main-dex-list path Especifica um arquivo de texto que lista classes que d8 precisa incluir no arquivo DEX principal, normalmente denominado classes.dex. Ou seja, quando você não especifica uma lista de classes usando essa sinalização, d8 não garante quais classes serão incluídas no arquivo DEX principal.

Como o sistema Android carrega primeiro o arquivo DEX principal ao iniciar seu app, você pode usar essa sinalização para priorizar determinadas classes na inicialização, compilando-as no arquivo DEX principal. Isso é especialmente útil quando houver compatibilidade com o legado multidex, porque somente as classes no arquivo DEX principal ficam disponíveis durante o tempo de execução até que a biblioteca de legado multidex seja carregada.

Lembre-se de que cada arquivo DEX ainda precisa atender ao limite de referência de 64 K. Portanto, não especifique muitas classes para o arquivo DEX principal para que não haja um erro de compilação. Por padrão, ao especificar classes usando --main-dex-list, d8 inclui apenas as classes no arquivo DEX principal. O objetivo é facilitar a depuração de problemas relacionados a classes ausentes do arquivo DEX principal. Se você especificar o modo --release, d8 tentará reduzir o número de arquivos DEX empacotados na versão de lançamento do app incluindo o máximo possível de outras classes no arquivo DEX principal, até atingir o limite de 64 K.

Não é possível usar essa sinalização ao especificar --file-per-class.

--version Exibe a versão do d8 que você está usando no momento.
--help Exibe o texto de ajuda para usar d8

Executar builds incrementais

Para melhorar as velocidades de compilação durante o desenvolvimento, como para builds de integração contínua, é possível instruir d8 para compilar apenas um subconjunto do bytecode Java do seu projeto. Por exemplo, se você ativar a dexação por classe, será possível recompilar somente as classes que você modificou desde o build anterior.

O comando a seguir executa um build incremental de algumas classes e ativa a dexação por classe. O comando também especifica um diretório de saída para o build incremental.

d8 MainActivity.class R.class --intermediate --file-per-class --output ~/build/intermediate/dex

Quando d8 executa um build incremental, ele armazena outras informações na saída DEX, que são usadas posteriormente para o processamento certo da opção --main-dex-list e combinação de arquivos DEX durante um build completo do app. Por exemplo, ao processar classes lambda do Java 8, d8 mantém o controle de quais classes lambda são criadas para cada classe de entrada. Em um build completo, quando d8 inclui uma classe no arquivo DEX principal, ele consulta os metadados para garantir que todas as classes lambda criadas para essa classe também sejam incluídas no arquivo DEX principal.

Caso já tenha compilado todo o bytecode do seu projeto em arquivos DEX em vários builds incrementais, é possível fazer um build completo transmitindo o diretório de arquivos DEX intermediários para d8, conforme mostrado abaixo. Além disso, você pode especificar as classes que quer que d8 compile no arquivo DEX principal usando --main-dex-list. Como a entrada é um conjunto de arquivos que já está compilado no bytecode DEX, esse build provavelmente será concluído mais rapidamente que um build limpo.

d8 ~/build/intermediate/dex --release --main-dex-list ~/build/classes.txt --output ~/build/release/dex

Compilar bytecode que usa recursos da linguagem Java 8

d8 permite usar recursos da linguagem Java 8 no seu código por meio de um processo de compilação chamado simplificação, que converte esses recursos de linguagem úteis em bytecode que possa ser executado na plataforma Android.

O Android Studio e o Plug-in do Android para Gradle incluem recursos de caminho de classe que d8 exige para ativar esse processo para você. No entanto, ao usar d8 na linha de comando, você mesmo precisa incluí-los.

Um desses recursos é o android.jar do SDK do Android de destino. Esse recurso inclui um conjunto de APIs da plataforma Android e o caminho precisa ser especificado usando a sinalização --lib.

Outro recurso é o conjunto de bytecode Java do projeto que não está sendo compilado em bytecode DEX no momento, mas é necessário para compilar outras classes no bytecode DEX. Por exemplo, caso seu código use métodos de interface padrão e estática (link em inglês), que é um recurso da linguagem Java 8, use essa sinalização para especificar o caminho para todo o bytecode Java do projeto, mesmo que não pretenda compilar tudo em bytecode DEX. Isso porque d8 precisa dessas informações para entender o código do projeto e resolver chamadas para os métodos da interface.

A amostra de código a seguir executa um build incremental de uma classe que acessa um método de interface padrão:

d8 MainActivity.class --intermediate --file-per-class --output ~/build/intermediate/dex
--lib android_sdk/platforms/api-level/android.jar
--classpath ~/build/javac/debug