Jack เป็นเครื่องมือเริ่มต้นของ Android build toolchain สำหรับ Android 6.0 - 8.1
Jack เป็นเครื่องมือของ Android toolchain ที่คอมไพล์ซอร์สโค้ด Java เป็น bytecode dex ของ Android คุณไม่จำเป็นต้องทำอะไรแตกต่างออกไปเพื่อใช้ Jack เพียงใช้คำสั่ง makefile มาตรฐานเพื่อคอมไพล์ทรีหรือโปรเจ็กต์ Android 8.1 เป็นเวอร์ชันล่าสุดที่ใช้ Jack
เกี่ยวกับ Jack
Jack ทำงานตามที่แสดงในรูปที่ 1
รูปที่ 1 ภาพรวมของ Jack
รูปแบบไลบรารีของ Jack
Jack มีรูปแบบไฟล์ .jack ของตัวเองซึ่งมีโค้ด dex ที่คอมไพล์ไว้ล่วงหน้าสำหรับไลบรารี ซึ่งช่วยให้คอมไพล์ได้เร็วขึ้น (pre-dex)
รูปที่ 2 เนื้อหาไฟล์ไลบรารีของ Jack
Jill
เครื่องมือ Jill จะแปลไลบรารี .jar ที่มีอยู่เป็นรูปแบบไลบรารีใหม่ ดังที่แสดงในรูปต่อไปนี้
รูปที่ 3 เวิร์กโฟลว์ในการนำเข้าไลบรารี .jar ที่มีอยู่
เซิร์ฟเวอร์การคอมไพล์ของ Jack
เมื่อใช้ Jack เป็นครั้งแรก ระบบจะเปิดเซิร์ฟเวอร์การคอมไพล์ของ Jack ในเครื่องคอมพิวเตอร์ของคุณ เซิร์ฟเวอร์นี้มีหน้าที่ดังนี้
- ช่วยเพิ่มความเร็วโดยธรรมชาติเนื่องจากไม่ต้องเปิดใช้ JRE JVM โฮสต์ใหม่ โหลดโค้ด Jack เริ่มต้น Jack และวอร์ม JIT ทุกครั้งที่คอมไพล์ นอกจากนี้ยังช่วยให้คอมไพล์ได้เร็วมากเมื่อคอมไพล์ขนาดเล็ก (เช่น ในโหมดเพิ่ม)
- เป็นโซลูชันระยะสั้นในการควบคุมจำนวนการคอมไพล์ของ Jack ที่โหลดพร้อมกัน เซิร์ฟเวอร์จะช่วยไม่ให้คอมพิวเตอร์ของคุณทำงานหนักเกินไป (ปัญหาเกี่ยวกับหน่วยความจำหรือดิสก์) เนื่องจากจำกัดจำนวนการคอมไพล์ที่โหลดพร้อมกัน
เซิร์ฟเวอร์ Jack จะปิดตัวเองหลังจากไม่มีการใช้งานเป็นระยะเวลาหนึ่งโดยไม่มีการคอมไพล์
โดยจะใช้พอร์ต TCP 2 พอร์ตในอินเทอร์เฟซ localhost และไม่สามารถใช้งานภายนอกได้ คุณสามารถแก้ไขพารามิเตอร์ทั้งหมด (จำนวนการคอมไพล์ที่โหลดพร้อมกัน การหมดเวลา หมายเลขพอร์ต ฯลฯ) ได้โดยแก้ไขไฟล์ $HOME/.jack
ไฟล์ $HOME/.jack
ไฟล์ $HOME/.jack มีการตั้งค่าต่อไปนี้สำหรับตัวแปรเซิร์ฟเวอร์ Jack ในไวยากรณ์ bash แบบเต็ม
SERVER=trueจะเปิดใช้ฟีเจอร์เซิร์ฟเวอร์ของ JackSERVER_PORT_SERVICE=8072จะตั้งค่าหมายเลขพอร์ต TCP ของเซิร์ฟเวอร์เพื่อวัตถุประสงค์ในการคอมไพล์SERVER_PORT_ADMIN=8073จะตั้งค่าหมายเลขพอร์ต TCP ของเซิร์ฟเวอร์เพื่อวัตถุประสงค์ในการดูแลระบบSERVER_COUNT=1ไม่ได้ใช้SERVER_NB_COMPILE=4จะตั้งค่าจำนวนการคอมไพล์ที่โหลดพร้อมกันสูงสุดที่อนุญาตSERVER_TIMEOUT=60จะตั้งค่าจำนวนวินาทีที่เซิร์ฟเวอร์ต้องรอโดยไม่มีการคอมไพล์ก่อนที่จะปิดตัวเองSERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}จะตั้งค่าไฟล์ที่ระบบจะเขียนบันทึกของเซิร์ฟเวอร์ โดยค่าเริ่มต้น ตัวแปรนี้สามารถโหลดซ้ำได้ด้วยตัวแปรสภาพแวดล้อมJACK_VM_COMMAND=${JACK_VM_COMMAND:=java}จะตั้งค่าคำสั่งเริ่มต้นที่ใช้ในการเปิดใช้ JVM ในโฮสต์ โดยค่าเริ่มต้น ตัวแปรนี้สามารถโหลดซ้ำได้ด้วยตัวแปรสภาพแวดล้อม
แก้ปัญหาการคอมไพล์ของ Jack
| ปัญหา | การทำงาน |
|---|---|
| คอมพิวเตอร์ไม่ตอบสนองระหว่างการคอมไพล์ หรือคุณพบว่าการคอมไพล์ของ Jack ล้มเหลวเนื่องจาก Out of memory error | ลดจำนวนการคอมไพล์ของ Jack ที่โหลดพร้อมกันโดยแก้ไข $HOME/.jack และเปลี่ยน SERVER_NB_COMPILE เป็นค่าที่ต่ำลง |
| การคอมไพล์ล้มเหลวเนื่องจาก Cannot launch background server | สาเหตุที่เป็นไปได้มากที่สุดคือพอร์ต TCP ถูกใช้ในคอมพิวเตอร์ของคุณแล้ว เปลี่ยนพอร์ตโดยแก้ไข $HOME/.jack (ตัวแปร SERVER_PORT_SERVICE และ SERVER_PORT_ADMIN) หากต้องการยกเลิกการบล็อกสถานการณ์ ให้ปิดใช้เซิร์ฟเวอร์การคอมไพล์ของ Jack
โดยแก้ไข $HOME/.jack และเปลี่ยน
SERVER เป็น false แต่น่าเสียยดายที่การดำเนินการนี้จะทำให้การคอมไพล์ช้าลงอย่างมาก
และอาจบังคับให้คุณเปิดใช้ make -j ด้วยการควบคุมการโหลด (ตัวเลือก -l ของ make) |
| การคอมไพล์ค้างโดยไม่มีความคืบหน้า | หากต้องการยกเลิกการบล็อกสถานการณ์ ให้หยุดเซิร์ฟเวอร์เบื้องหลังของ Jack โดยใช้ jack-admin kill-server) จากนั้นนำไดเรกทอรีชั่วคราวที่อยู่ใน jack-$USER ของไดเรกทอรีชั่วคราว (/tmp หรือ $TMPDIR) ออก |
ค้นหาบันทึกของ Jack
หากคุณเรียกใช้คำสั่ง make ด้วยเป้าหมาย dist บันทึกของ Jack จะอยู่ที่ $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log
มิเช่นนั้น คุณจะค้นหาบันทึกได้โดยเรียกใช้ jack-admin server-log
ในกรณีที่ Jack ล้มเหลวซ้ำๆ คุณจะได้รับบันทึกโดยละเอียดมากขึ้นโดยตั้งค่าตัวแปรต่อไปนี้
export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"
ใช้คำสั่ง makefile มาตรฐานเพื่อคอมไพล์ทรี (หรือโปรเจ็กต์) และแนบเอาต์พุตและข้อผิดพลาดมาตรฐาน หากต้องการนำบันทึกการสร้างโดยละเอียดออก ให้เรียกใช้คำสั่งต่อไปนี้
unset ANDROID_JACK_EXTRA_ARGS
ข้อจำกัดของ Jack
โดยค่าเริ่มต้น ผู้ใช้เพียงคนเดียวเท่านั้นที่ใช้เซิร์ฟเวอร์ Jack ในคอมพิวเตอร์ได้ หากต้องการรองรับผู้ใช้เพิ่มเติม ให้เลือกหมายเลขพอร์ตที่แตกต่างกันสำหรับผู้ใช้แต่ละรายและปรับ SERVER_NB_COMPILE ตามความเหมาะสม นอกจากนี้ คุณยังปิดใช้เซิร์ฟเวอร์ Jack ได้โดยตั้งค่า SERVER=false ใน $HOME/.jack
การคอมไพล์ CTS ช้าเนื่องจากการผสานรวม vm-tests-tf ในปัจจุบัน
ระบบไม่รองรับเครื่องมือจัดการ bytecode (เช่น JaCoCo)
ใช้ Jack
Jack รองรับภาษาโปรแกรม Java 1.7 และผสานรวมฟีเจอร์เพิ่มเติมที่อธิบายไว้ด้านล่าง
Pre-dex
เมื่อสร้างไฟล์ไลบรารีของ Jack ระบบจะสร้าง .dex ของไลบรารีและจัดเก็บไว้ในไฟล์ไลบรารี .jack เป็น pre-dex
เมื่อคอมไพล์ Jack จะใช้ pre-dex จากแต่ละไลบรารีซ้ำ ไลบรารีทั้งหมดจะได้รับการ pre-dex
รูปที่ 4 ไลบรารีของ Jack ที่มี pre-dex
Jack จะไม่ใช้ pre-dex ของไลบรารีซ้ำหากใช้การลดขนาด การปรับให้ยากต่อการอ่าน หรือการจัดแพ็กเกจใหม่ในการคอมไพล์
การคอมไพล์แบบเพิ่ม
การคอมไพล์แบบเพิ่มหมายความว่าระบบจะคอมไพล์ซ้ำเฉพาะคอมโพเนนต์ที่มีการเปลี่ยนแปลงตั้งแต่การคอมไพล์ครั้งล่าสุด (และทรัพยากร Dependency ของคอมโพเนนต์เหล่านั้น) การคอมไพล์แบบเพิ่มอาจเร็วกว่าการคอมไพล์แบบเต็มอย่างมากเมื่อการเปลี่ยนแปลงจำกัดอยู่เพียงชุดคอมโพเนนต์
การคอมไพล์แบบเพิ่มจะปิดใช้โดยค่าเริ่มต้น (และจะปิดใช้งานโดยอัตโนมัติเมื่อเปิดใช้การลดขนาด การปรับให้ยากต่อการอ่าน การจัดแพ็กเกจใหม่ หรือ multidex เวอร์ชันเก่า) หากต้องการเปิดใช้บิลด์แบบเพิ่ม ให้เพิ่มบรรทัดต่อไปนี้ลงในไฟล์ Android.mk ของโปรเจ็กต์ที่ต้องการสร้างแบบเพิ่ม
LOCAL_JACK_ENABLED := incremental
การลดขนาดและการปรับให้ยากต่อการอ่าน
Jack ใช้ไฟล์การกำหนดค่า ProGuard เพื่อเปิดใช้การลดขนาดและการปรับให้ยากต่อการอ่าน
ตัวเลือกทั่วไปมีดังนี้
@-include-basedirectory-injars-outjars(รองรับ jar เอาต์พุตเพียง 1 รายการ)-libraryjars-keep-keepclassmembers-keepclasseswithmembers-keepnames-keepclassmembernames-keepclasseswithmembernames-printseeds
ตัวเลือกการลดขนาดมีดังนี้
-dontshrink
ตัวเลือกการปรับให้ยากต่อการอ่านมีดังนี้
-dontobfuscate-printmapping-applymapping-obfuscationdictionary-classobfuscationdictionary-packageobfuscationdictionary-useuniqueclassmembernames-dontusemixedcaseclassnames-keeppackagenames-flattenpackagehierarchy-repackageclasses-keepattributes-adaptclassstrings
ตัวเลือกที่ระบบจะข้ามมีดังนี้
-dontoptimize(Jack ไม่เพิ่มประสิทธิภาพ)-dontpreverify(Jack ไม่ตรวจสอบล่วงหน้า)-skipnonpubliclibraryclasses-dontskipnonpubliclibraryclasses-dontskipnonpubliclibraryclassmembers-keepdirectories-target-forceprocessing-printusage-whyareyoukeeping-optimizations-optimizationpasses-assumenosideeffects-allowaccessmodification-mergeinterfacesaggressively-overloadaggressively-microedition-verbose-dontnote-dontwarn-ignorewarnings-printconfiguration-dump
การจัดแพ็กเกจใหม่
Jack ใช้ไฟล์การกำหนดค่า jarjar เพื่อจัดแพ็กเกจใหม่ แม้ว่า Jack จะเข้ากันได้กับประเภทกฎ "rule" แต่ก็ไม่เข้ากันได้กับประเภทกฎ "zap" หรือ "keep"
การรองรับ multidex
Jack มีการรองรับ multidex ในตัวและเวอร์ชันเก่า เนื่องจากไฟล์ dex จำกัดไว้ที่ 65,000 เมธอด แอปที่มีเมธอดมากกว่า 65,000 เมธอดจึงต้องแยกออกเป็นไฟล์ dex หลายไฟล์ โปรดดูรายละเอียดเพิ่มเติมที่หัวข้อ เปิดใช้ multidex สำหรับแอปที่มีเมธอดมากกว่า 64, 000 เมธอด