Jack był domyślnym łańcuchem narzędzi do kompilowania Androida w wersjach 6.0–8.1. Służył do kompilowania kodu źródłowego Java do kodu bajtowego Androida dex, jak pokazano na ilustracji 1:
Ilustracja 1. Omówienie narzędzia Jack.
Format pliku .jack zawiera wstępnie skompilowany kod dex biblioteki, co przyspiesza kompilację (wstępna kompilacja dex).
Ilustracja 2. Zawartość pliku biblioteki Jack.
Narzędzie Jill
Narzędzie Jill tłumaczy istniejące biblioteki .jar na nowy format biblioteki .jack, jak pokazano na ilustracji 3:
Ilustracja 3. Proces importowania istniejącej biblioteki .jar.
Serwer kompilacji Jack
Gdy używasz narzędzia Jack po raz pierwszy, uruchamia ono na Twoim komputerze lokalny serwer kompilacji Jack. Ten serwer:
- przyspiesza działanie, ponieważ unika uruchamiania nowej maszyny JVM hosta JRE, wczytywania kodu Jack, inicjowania Jack i rozgrzewania JIT przy każdej kompilacji. Zapewnia też bardzo dobre czasy kompilacji podczas małych kompilacji (np. w trybie przyrostowym).
- jest rozwiązaniem krótkoterminowym, które pozwala kontrolować liczbę równoległych kompilacji Jack. Serwer unika przeciążenia komputera (problemów z pamięcią lub dyskiem), ponieważ ogranicza liczbę równoległych kompilacji.
Serwer Jack wyłącza się po upływie czasu bezczynności bez kompilacji. Używa 2 portów TCP w interfejsie localhost i nie jest dostępny z zewnątrz.
Wszystkie parametry (np. liczba równoległych kompilacji, limit czasu i numery portów) można modyfikować, edytując plik $HOME/.jack.
Plik $HOME/.jack
Plik $HOME/.jack zawiera te ustawienia zmiennych serwera Jack w pełnej składni bash:
SERVER=truewłącza funkcję serwera Jack.SERVER_PORT_SERVICE=8072ustawia numer portu TCP serwera na potrzeby kompilacji.SERVER_PORT_ADMIN=8073ustawia numer portu TCP serwera na potrzeby administracji.SERVER_COUNT=1jest nieużywane.SERVER_NB_COMPILE=4ustawia maksymalną liczbę dozwolonych równoległych kompilacji.SERVER_TIMEOUT=60ustawia liczbę sekund bezczynności, po których serwer musi poczekać bez kompilacji, zanim się wyłączy.SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}ustawia plik, w którym zapisywane są logi serwera. Domyślnie tę zmienną można zastąpić zmienną środowiskową.JACK_VM_COMMAND=${JACK_VM_COMMAND:=java}ustawia domyślne polecenie używane do uruchamiania maszyny JVM na hoście. Domyślnie tę zmienną można zastąpić zmienną środowiskową.
Rozwiązywanie problemów z kompilacjami Jack
| Problem | Działanie |
|---|---|
| Podczas kompilacji komputer przestaje odpowiadać lub kompilacje Jack kończą się niepowodzeniem z powodu błędu braku pamięci. | Zmniejsz liczbę jednoczesnych kompilacji Jack, edytując plik $HOME/.jack i zmieniając wartość SERVER_NB_COMPILE na mniejszą. |
| Kompilacje kończą się niepowodzeniem z powodu nie można uruchomić serwera w tle. | Najprawdopodobniej porty TCP są już używane na Twoim komputerze. Zmień porty, edytując plik $HOME/.jack (zmienne SERVER_PORT_SERVICE i SERVER_PORT_ADMIN). Aby odblokować sytuację, wyłącz serwer kompilacji Jack, edytując $HOME/.jack i zmieniając
SERVER na false. Niestety znacznie spowolni to
kompilację i może zmusić Cię do uruchomienia make -j z kontrolą
obciążenia (opcja -l polecenia make). |
| Kompilacja zawiesza się bez postępu. | Aby odblokować sytuację, zatrzymaj serwer w tle Jack za pomocą polecenia jack-admin kill-server, a następnie usuń katalogi tymczasowe znajdujące się w katalogu tymczasowym (/tmp lub $TMPDIR) w katalogu jack-$USER. |
Znajdowanie logu Jack
Jeśli polecenie make zostało uruchomione z celem dist, log Jack znajduje się w lokalizacji $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log. W przeciwnym razie log można znaleźć, uruchamiając polecenie jack-admin server-log. W przypadku powtarzających się błędów Jack możesz uzyskać bardziej szczegółowy log, ustawiając tę zmienną:
export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"
Użyj standardowych poleceń makefile, aby skompilować drzewo (lub projekt) i dołączyć standardowe dane wyjściowe oraz błędy. Aby usunąć szczegółowe logi kompilacji, uruchom:
unset ANDROID_JACK_EXTRA_ARGS
Ograniczenia narzędzia Jack
Domyślnie serwer Jack może być używany tylko przez 1 użytkownika na komputerze. Aby obsługiwać dodatkowych użytkowników, wybierz różne numery portów dla każdego użytkownika i odpowiednio dostosuj wartość SERVER_NB_COMPILE. Możesz też wyłączyć serwer Jack, ustawiając wartość SERVER=false w pliku $HOME/.jack. Kompilacja CTS jest powolna z powodu bieżącej integracji vm-tests-tf. Narzędzia do manipulowania kodem bajtowym (np. JaCoCo) nie są obsługiwane.
Używanie narzędzia Jack
Narzędzie Jack obsługuje język programowania Java 1.7 i integruje dodatkowe funkcje opisane w tej sekcji. Użyj standardowych poleceń makefile, aby skompilować drzewo lub projekt.
Wstępna kompilacja dex
Podczas generowania pliku biblioteki Jack plik .dex biblioteki jest generowany i przechowywany w pliku biblioteki .jack jako wstępnie skompilowany plik dex. Podczas kompilacji narzędzie Jack ponownie używa wstępnie skompilowanego pliku dex z każdej biblioteki. Wszystkie biblioteki są wstępnie kompilowane do formatu dex.
Ilustracja 4. Biblioteki Jack ze wstępnie skompilowanym plikiem dex.
Narzędzie Jack nie używa wstępnie skompilowanego pliku dex biblioteki, jeśli w kompilacji używane jest zmniejszanie, zaciemnianie lub przepakowywanie.
Kompilacja przyrostowa
Kompilacja przyrostowa oznacza, że kompilowane są tylko te komponenty, które zostały zmienione od czasu ostatniej kompilacji (i ich zależności). Kompilacja przyrostowa może być znacznie szybsza niż pełna kompilacja, gdy zmiany są ograniczone do zestawu komponentów.
Kompilacja przyrostowa jest domyślnie wyłączona (i jest automatycznie dezaktywowana, gdy włączone jest zmniejszanie, zaciemnianie, przepakowywanie lub starsza wersja multidex). Aby włączyć kompilacje przyrostowe, dodaj ten wiersz do pliku Android.mk projektu, który chcesz skompilować przyrostowo:
LOCAL_JACK_ENABLED := incremental
Zmniejszanie i zaciemnianie
Narzędzie Jack używa plików konfiguracji ProGuard, aby włączyć zmniejszanie i zaciemnianie. Typowe opcje:
@-include-basedirectory-injars-outjars(obsługiwany jest tylko 1 wyjściowy plik jar)-libraryjars-keep-keepclassmembers-keepclasseswithmembers-keepnames-keepclassmembernames-keepclasseswithmembernames-printseeds
Opcje zmniejszania:
-dontshrink
Opcje zaciemniania:
-dontobfuscate-printmapping-applymapping-obfuscationdictionary-classobfuscationdictionary-packageobfuscationdictionary-useuniqueclassmembernames-dontusemixedcaseclassnames-keeppackagenames-flattenpackagehierarchy-repackageclasses-keepattributes-adaptclassstrings
Ignorowane opcje:
-dontoptimize(Jack nie optymalizuje)-dontpreverify(Jack nie przeprowadza wstępnej weryfikacji)-skipnonpubliclibraryclasses-dontskipnonpubliclibraryclasses-dontskipnonpubliclibraryclassmembers-keepdirectories-target-forceprocessing-printusage-whyareyoukeeping-optimizations-optimizationpasses-assumenosideeffects-allowaccessmodification-mergeinterfacesaggressively-overloadaggressively-microedition-verbose-dontnote-dontwarn-ignorewarnings-printconfiguration-dump
Przepakowywanie
Narzędzie Jack używa plików konfiguracji jarjar do przepakowywania. Narzędzie Jack jest zgodne z typami reguł rule, ale nie jest zgodne z typami reguł zap ani keep.
Obsługa multidex
Narzędzie Jack oferuje wbudowaną i starszą obsługę multidex. Ponieważ pliki dex są ograniczone do 65 tys. metod, aplikacje z ponad 65 tys. metod muszą być podzielone na kilka plików dex. Więcej informacji znajdziesz w artykule Włączanie multidex w aplikacjach z ponad 64 tys. metod.