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 e 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 Ferramentas de build 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, como 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 o d8 os mescle 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, precisará passar a sinalização -g para incluir informações de depuração no bytecode de saída Java.

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, o d8 inclui algumas informações usadas ao gerar rastreamentos de pilha e exceções de registros.

Passe 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, o d8 gera o arquivos DEX no diretório de trabalho atual.

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

--lib android_sdk/platforms/api-level/android.jar Especifica o caminho para o android.jar do SDK do Android. Esta sinalização é obrigatória ao compilar bytecode que usa recursos da linguagem Java 8.
--classpath path Especifica os recursos do caminho de classe necessários para o d8 compilar os arquivos DEX do seu projeto. Em particular, o d8 requer a especificação de determinados recursos ao compilar bytecode que usa recursos da linguagem Java 8.
--min-api number Especifica o nível mínimo de API com que você quer que os arquivos DEX de saída sejam compatíveis.
--intermediate Passe esta sinalização para informar ao d8 que você não está compilando o conjunto completo de bytecode Java do projeto. Esta sinalização é útil ao executar builds incrementais: em vez de compilar arquivos DEX otimizados que você espera executar em um dispositivo, o 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 esta 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 desta sinalização permite que você execute mais builds incrementais, recompilando apenas as classes que foram alteradas. Ao executar builds incrementais usando o Plug-in do Android para Gradle, esta 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 esta 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 o 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 primeiro carrega o arquivo DEX principal ao iniciar seu app, você pode usar esta sinalização para priorizar determinadas classes na inicialização, compilando-as no arquivo DEX principal. Isso é particularmente útil quando houver compatibilidade com o legado multidex, porque somente as classes no arquivo DEX principal ficam disponíveis no 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, o d8 inclui apenas as classes no arquivo DEX principal. Isso visa facilitar a depuração de problemas relacionados a classes ausentes do arquivo DEX principal. Se você especificar o modo --release, o d8 tentará reduzir o número de arquivos DEX empacotados na versão do seu 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 Imprime a versão do d8 que você está usando no momento.
--help Imprime o texto de ajuda para usar d8

Executar builds incrementais

Para melhorar a velocidade de criação durante o desenvolvimento, como para builds de integração contínua, você pode instruir o d8 para compilar apenas um subconjunto do bytecode Java do seu projeto. Por exemplo, se você ativar a dexação por classe, poderá 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 o d8 executa um build incremental, ele armazena informações adicionais na saída DEX que posteriormente usa para processar corretamente a opção --main-dex-list e mesclar arquivos DEX durante um build completo do seu app. Por exemplo, ao processar classes lambda do Java 8, d8 mantém o controle de quais classes lamdba são criadas para cada classe de entrada. Em um build completo, quando o 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.

Se você já tiver compilado todo o bytecode do seu projeto em arquivos DEX em vários builds incrementais, poderá fazer um build completo passando o diretório de arquivos DEX intermediários para o d8, conforme mostrado abaixo. Além disso, você pode especificar as classes que quer que o 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

O d8 permite usar recursos da linguagem Java 8 no seu código por meio de um processo de compilação chamado desugaring, que converte esses recursos de linguagem úteis em um bytecode que pode 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 o 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 seu projeto que você não está compilando em bytecode DEX, mas precisa para compilar outras classes no bytecode DEX. Por exemplo, se seu código usa métodos de interface padrão e estática (link em inglês), que é um recurso da linguagem Java 8, use esta 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 o 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 faz 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