O Jack é o conjunto de ferramentas padrão de build para as versões 6.0 a 8.1 do Android.
Ele era uma cadeia de ferramentas do Android que compilava fonte Java em bytecode dex do Android. Você não precisa fazer nada diferente para usar o Jack, apenas usar seus comandos makefile padrão para compilar a árvore ou o projeto. O Android 8.1 é a última versão que usa o Jack.
Sobre o Jack
O Jack funciona como mostrado na Figura 1.
Figura 1. Visão geral do Jack.
Formato da biblioteca do Jack
O Jack tem o próprio formato de arquivo .jack
, que contém o código dex pré-compilado para a biblioteca, possibilitando uma compilação mais rápida (pré-dex).
Figura 2. Conteúdo do arquivo da biblioteca do Jack.
Jill
Como mostrado na figura a seguir, a ferramenta Jill converte as
.jar
bibliotecas existentes para o novo formato.
Figura 3. Fluxo de trabalho para importar uma biblioteca .jar
já existente.
Servidor de compilação do Jack
A primeira vez que o Jack é usado, ele abre um servidor de compilação Jack local no seu computador, que:
- traz um aumento de velocidade intrínseco, porque evita a abertura de um novo host JRE JVM, o carregamento do código do Jack, a inicialização do Jack e o aquecimento do JIT a cada compilação. Ele também oferece tempos de compilação muito bons durante pequenas compilações (por exemplo, no modo incremental);
- é uma solução de curto prazo para controlar o número de compilações Jack paralelas. O servidor evita sobrecarregar seu computador (problema de memória ou de disco) porque limita o número de compilações paralelas.
O servidor do Jack é desativado após um período de inatividade sem nenhuma compilação.
Ele usa duas portas TCP na interface do localhost e não está disponível externamente. Todos os parâmetros (número de compilações paralelas, tempo limite, número de portas etc.) podem ser modificados editando o arquivo $HOME/.jack
.
Arquivo $HOME/.jack
O arquivo $HOME/.jack
contém as seguintes configurações para as variáveis do servidor do Jack em uma sintaxe bash completa:
SERVER=true
ativa o recurso de servidor do Jack.SERVER_PORT_SERVICE=8072
define o número da porta TCP do servidor para fins de compilação.SERVER_PORT_ADMIN=8073
define o número da porta TCP do servidor para fins administrativos.SERVER_COUNT=1
não é usado.SERVER_NB_COMPILE=4
define o número máximo de compilações paralelas permitidas.SERVER_TIMEOUT=60
define o número de segundos de inatividade que o servidor precisa aguardar sem nenhuma compilação antes de se desligar.SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}
define o arquivo em que os registros do servidor são gravados. Por padrão, essa variável pode ser sobrecarregada por uma variável de ambiente.JACK_VM_COMMAND=${JACK_VM_COMMAND:=java}
define o comando padrão usado para iniciar uma JVM no host. Por padrão, essa variável pode ser sobrecarregada pela variável de ambiente.
Resolver problemas de compilação do Jack
Problema | Ação |
---|---|
Seu computador deixa de responder durante a compilação ou você percebe que as compilações do Jack falham com Erro de falta de memória | Reduza o número de compilações simultâneas do Jack editando $HOME/.jack e mudando SERVER_NB_COMPILE para um valor mais baixo. |
As compilações estão falhando, apresentando o erro Não é possível iniciar o servidor em segundo plano | A causa mais provável é que as portas TCP já estão sendo usadas no seu computador. Mude as portas editando $HOME/.jack (as variáveis SERVER_PORT_SERVICE e SERVER_PORT_ADMIN ). Para resolver a situação, desative o servidor de compilação do Jack editando $HOME/.jack e mudando SERVER para false . Infelizmente, isso diminui significativamente a velocidade da sua compilação e pode obrigar você a abrir make -j com controle de carga (opção -l de make ). |
A compilação é interrompida sem qualquer progresso | Para resolver a situação, elimine o servidor em segundo plano do Jack usando
jack-admin kill-server e remova os diretórios temporários
contidos em jack-$USER do seu diretório temporário
(/tmp ou $TMPDIR ). |
Encontrar o registro do Jack
Se você executar um comando make
com um destino dist, o registro do Jack estará
localizado em $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log
.
Caso contrário, você poderá encontrar o log executando jack-admin server-log
.
Em caso de falhas do Jack reproduzíveis, veja um log mais detalhado definindo a seguinte variável:
export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"
Use comandos makefile padrão para compilar a árvore (ou seu projeto) e anexar a saída padrão e o erro. Para remover os logs de criação detalhados, execute:
unset ANDROID_JACK_EXTRA_ARGS
Limitações do Jack
Por padrão, o servidor do Jack pode ser usado por apenas um usuário em um computador. Para aceitar mais usuários, selecione diferentes números de porta para cada um
deles e ajuste o SERVER_NB_COMPILE
corretamente. Você também pode desativar
o servidor do Jack configurando SERVER=false
em $HOME/.jack
.
A compilação do CTS é lenta devido à integração atual do vm-tests-tf
.
As ferramentas de manipulação de bytecode (como o JaCoCo) não têm suporte.
Usar o Jack
O Jack tem suporte à linguagem de programação Java 1.7 e integra os recursos descritos abaixo.
Pré-dexação
Ao gerar um arquivo de biblioteca do Jack, o .dex
da biblioteca é gerado e armazenado dentro do arquivo de biblioteca .jack
como um pré-dex.
Durante a compilação, o Jack reutiliza o pré-dex de cada biblioteca. Todas as bibliotecas são
pré-dexadas.
Figura 4. Bibliotecas do Jack com pré-dex.
O Jack não reutiliza a pré-dexação da biblioteca quando a redução, a ofuscação ou o reempacotamento são usados na compilação.
Compilação incremental
Compilação incremental significa que somente os componentes modificados desde a última compilação (e as dependências deles) são recompilados. A compilação incremental pode ser significativamente mais rápida do que uma compilação completa quando as mudanças se limitam a um conjunto de componentes.
A compilação incremental é desativada por padrão. A desativação é automática
quando a redução, o ofuscamento, o reempacotamento ou o legado de multidex está
ativado. Para ativar builds incrementais, adicione a linha abaixo ao
arquivo Android.mk
do projeto que você quer criar de forma incremental:
LOCAL_JACK_ENABLED := incremental
Redução e ofuscação
O Jack usa arquivos de configuração do ProGuard para permitir a redução e a ofuscação.
Entre as opções comuns estão as seguintes:
@
-include
-basedirectory
-injars
-outjars
(é permitido apenas 1 jar de saída)-libraryjars
-keep
-keepclassmembers
-keepclasseswithmembers
-keepnames
-keepclassmembernames
-keepclasseswithmembernames
-printseeds
Entre as opções de redução está a seguinte:
-dontshrink
Entre as opções de ofuscação estão as seguintes:
-dontobfuscate
-printmapping
-applymapping
-obfuscationdictionary
-classobfuscationdictionary
-packageobfuscationdictionary
-useuniqueclassmembernames
-dontusemixedcaseclassnames
-keeppackagenames
-flattenpackagehierarchy
-repackageclasses
-keepattributes
-adaptclassstrings
Entre as opções ignoradas estão as seguintes:
-dontoptimize
(Jack não otimiza)-dontpreverify
(Jack não faz a pré-verificação)-skipnonpubliclibraryclasses
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-keepdirectories
-target
-forceprocessing
-printusage
-whyareyoukeeping
-optimizations
-optimizationpasses
-assumenosideeffects
-allowaccessmodification
-mergeinterfacesaggressively
-overloadaggressively
-microedition
-verbose
-dontnote
-dontwarn
-ignorewarnings
-printconfiguration
-dump
Reempacotamento
O Jack usa arquivos de configuração jarjar para realizar o reempacotamento. Embora o Jack seja compatível com os tipos de regra "rule", ele não é compatível com os tipos de regra "zap" ou "keep".
Compatibilidade com multidex
O Jack oferece suporte nativo e legado com multidex. Como os arquivos dex estão limitados a 65 mil métodos, os apps com mais do que isso precisam ser divididos em vários arquivos dex. Para mais detalhes, consulte Ativar multidex para apps com mais de 64 mil métodos.