Android 12 มีการเปลี่ยนแปลงระบบการสร้างการคอมไพล์ AOT ของไฟล์ DEX (dexpreopt) สำหรับโมดูล Java ที่มีการพึ่งพา <uses-library>
ในบางกรณีการเปลี่ยนแปลงระบบบิลด์เหล่านี้อาจทำให้บิลด์เสียหายได้ ใช้หน้านี้เพื่อเตรียมพร้อมสำหรับการแตกหัก และปฏิบัติตามสูตรอาหารในหน้านี้เพื่อแก้ไขและบรรเทา
Dexpreopt เป็นกระบวนการรวบรวมไลบรารีและแอป Java ล่วงหน้า Dexpreopt เกิดขึ้นบนโฮสต์ ณ เวลาสร้าง (ตรงข้ามกับ dexopt ซึ่งเกิดขึ้นบนอุปกรณ์) โครงสร้างการพึ่งพาไลบรารีแบบแบ่งใช้ที่ใช้โดยโมดูล Java (ไลบรารีหรือแอป) เรียกว่า class loader context (CLC) เพื่อรับประกันความถูกต้องของ dexpreopt CLC ของ build-time และ run-time จะต้องตรงกัน Build-time CLC คือสิ่งที่คอมไพเลอร์ dex2oat ใช้ในเวลา dexpreopt (บันทึกไว้ในไฟล์ ODEX) และ CLC รันไทม์คือบริบทที่มีการโหลดโค้ดที่คอมไพล์ไว้ล่วงหน้าบนอุปกรณ์
CLC เวลาในการสร้างและรันไทม์เหล่านี้ต้องตรงกันด้วยเหตุผลทั้งความถูกต้องและประสิทธิภาพ เพื่อความถูกต้อง จำเป็นต้องจัดการคลาสที่ซ้ำกัน หากการขึ้นต่อกันของไลบรารีแบบแบ่งใช้ ณ รันไทม์แตกต่างจากที่ใช้สำหรับการคอมไพล์ คลาสบางคลาสอาจได้รับการแก้ไขแตกต่างออกไป ทำให้เกิดข้อบกพร่องรันไทม์เล็กน้อย ประสิทธิภาพยังได้รับผลกระทบจากการตรวจสอบรันไทม์สำหรับคลาสที่ซ้ำกัน
กรณีการใช้งานที่ได้รับผลกระทบ
การบูตครั้งแรกเป็นกรณีการใช้งานหลักที่ได้รับผลกระทบจากการเปลี่ยนแปลงเหล่านี้: หาก ART ตรวจพบความไม่ตรงกันระหว่าง CLC ในเวลาบิลด์และรันไทม์ ระบบจะปฏิเสธสิ่งประดิษฐ์ dexpreopt และเรียกใช้ dexopt แทน สำหรับการบูทครั้งต่อๆ ไปก็เป็นเรื่องปกติ เพราะแอปต่างๆ สามารถจัดทำ dexopted ในพื้นหลังและจัดเก็บไว้ในดิสก์ได้
พื้นที่ที่ได้รับผลกระทบจาก Android
สิ่งนี้ส่งผลต่อแอพและไลบรารี Java ทั้งหมดที่มีการพึ่งพารันไทม์บนไลบรารี Java อื่น ๆ Android มีแอปหลายพันรายการ และอีกหลายร้อยแอปใช้ไลบรารีที่แชร์ พันธมิตรก็ได้รับผลกระทบเช่นกัน เนื่องจากมีไลบรารีและแอปของตนเอง
ทำลายการเปลี่ยนแปลง
ระบบบิลด์จำเป็นต้องทราบการพึ่งพา <uses-library>
ก่อนที่จะสร้างกฎการสร้าง dexpreopt อย่างไรก็ตาม ไม่สามารถเข้าถึงไฟล์ Manifest ได้โดยตรงและอ่านแท็ก <uses-library>
ในนั้นได้ เนื่องจากระบบบิลด์ไม่ได้รับอนุญาตให้อ่านไฟล์ที่กำหนดเองเมื่อสร้างกฎการบิลด์ (เพื่อเหตุผลด้านประสิทธิภาพ) นอกจากนี้ ไฟล์ Manifest อาจถูกจัดแพ็กเกจไว้ภายใน APK หรือที่สร้างไว้ล่วงหน้า ดังนั้น ข้อมูล <uses-library>
จะต้องมีอยู่ในไฟล์บิลด์ ( Android.bp
หรือ Android.mk
)
ก่อนหน้านี้ ART ใช้วิธีแก้ปัญหาที่ละเว้นการพึ่งพาไลบรารีที่ใช้ร่วมกัน (เรียกว่า &-classpath
) สิ่งนี้ไม่ปลอดภัยและทำให้เกิดข้อบกพร่องเล็กน้อย ดังนั้นวิธีแก้ปัญหาเบื้องต้นจึงถูกลบออกใน Android 12
ด้วยเหตุนี้ โมดูล Java ที่ไม่ได้ให้ข้อมูล <uses-library>
ที่ถูกต้องในไฟล์บิลด์อาจทำให้เกิด การแตกของบิลด์ (เกิดจาก CLC ในเวลาบิลด์ไม่ตรงกัน) หรือ การถดถอยของเวลาบูตครั้งแรก (เกิดจาก CLC ขณะบูต ไม่ตรงกันตามด้วย dexopt)
เส้นทางการอพยพ
ทำตามขั้นตอนเหล่านี้เพื่อแก้ไขบิลด์ที่เสียหาย:
ปิดใช้งานการตรวจสอบเวลาการสร้างทั่วโลกสำหรับผลิตภัณฑ์เฉพาะโดยการตั้งค่า
PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true
ใน makefile ของผลิตภัณฑ์ วิธีนี้จะแก้ไขข้อผิดพลาดของบิลด์ (ยกเว้นกรณีพิเศษ ซึ่งระบุไว้ในส่วน การแก้ไขการแตกหัก ) อย่างไรก็ตาม นี่เป็นวิธีแก้ปัญหาชั่วคราว และอาจทำให้ CLC ในเวลาบูตไม่ตรงกันตามด้วย dexopt
แก้ไขโมดูลที่ล้มเหลวก่อนที่คุณจะปิดใช้งานการตรวจสอบเวลาบิลด์ทั่วโลกโดยการเพิ่มข้อมูล
<uses-library>
ที่จำเป็นลงในไฟล์บิลด์ (ดู การแก้ไขการแตกหัก เพื่อดูรายละเอียด) สำหรับโมดูลส่วนใหญ่ จำเป็นต้องเพิ่มสองสามบรรทัดในAndroid.bp
หรือในAndroid.mk
ปิดใช้งานการตรวจสอบเวลาบิวด์และ dexpreopt สำหรับกรณีที่มีปัญหา ในแต่ละโมดูล ปิดใช้งาน dexpreopt เพื่อที่คุณจะได้ไม่ต้องเสียเวลาในการสร้างและพื้นที่เก็บข้อมูลกับอาร์ติแฟกต์ที่ถูกปฏิเสธเมื่อบูตเครื่อง
เปิดใช้งานการตรวจสอบเวลาบิลด์อีกครั้งทั่วโลกโดยยกเลิกการตั้งค่า
PRODUCT_BROKEN_VERIFY_USES_LIBRARIES
ที่ตั้งค่าไว้ในขั้นตอนที่ 1 การสร้างไม่ควรล้มเหลวหลังจากการเปลี่ยนแปลงนี้ (เนื่องจากขั้นตอนที่ 2 และ 3)แก้ไขโมดูลที่คุณปิดใช้งานในขั้นตอนที่ 3 ทีละโมดูล จากนั้นเปิดใช้งาน dexpreopt อีกครั้งและทำเครื่องหมาย
<uses-library>
แจ้งข้อบกพร่องหากจำเป็น
การตรวจสอบ <uses-library>
เวลาบิวด์บังคับใช้ใน Android 12
แก้ไขการแตกหัก
ส่วนต่อไปนี้จะบอกวิธีแก้ไขการแตกหักบางประเภท
ข้อผิดพลาดของบิลด์: CLC ไม่ตรงกัน
ระบบบิลด์จะทำการตรวจสอบการเชื่อมโยงกันในเวลาบิลด์ระหว่างข้อมูลในไฟล์ Android.bp
หรือ Android.mk
และไฟล์ Manifest ระบบบิลด์ไม่สามารถอ่านไฟล์ Manifest ได้ แต่สามารถสร้างกฎบิลด์เพื่ออ่านไฟล์ Manifest ได้ (แยกออกจาก APK หากจำเป็น) และเปรียบเทียบแท็ก <uses-library>
ในไฟล์ Manifest กับข้อมูล <uses-library>
ใน ไฟล์บิลด์ หากการตรวจสอบล้มเหลว ข้อผิดพลาดจะมีลักษณะดังนี้:
error: mismatch in the <uses-library> tags between the build system and the manifest:
- required libraries in build system: []
vs. in the manifest: [org.apache.http.legacy]
- optional libraries in build system: []
vs. in the manifest: [com.x.y.z]
- tags in the manifest (.../X_intermediates/manifest/AndroidManifest.xml):
<uses-library android:name="com.x.y.z"/>
<uses-library android:name="org.apache.http.legacy"/>
note: the following options are available:
- to temporarily disable the check on command line, rebuild with RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" and disable AOT-compilation in dexpreopt)
- to temporarily disable the check for the whole product, set PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles
- to fix the check, make build system properties coherent with the manifest
- see build/make/Changes.md for details
ตามข้อความแสดงข้อผิดพลาด มีวิธีแก้ไขหลายวิธี ขึ้นอยู่กับความเร่งด่วน:
- สำหรับ การแก้ไขชั่วคราวทั้งผลิตภัณฑ์ ให้ตั้งค่า
PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true
ใน makefile ของผลิตภัณฑ์ ยังคงดำเนินการตรวจสอบการเชื่อมโยงกันในเวลาบิลด์ แต่การตรวจสอบล้มเหลวไม่ได้หมายความว่าบิลด์ล้มเหลว ความล้มเหลวในการตรวจสอบจะทำให้ระบบบิลด์ดาวน์เกรดตัวกรองคอมไพเลอร์ dex2oat เพื่อverify
ใน dexpreopt ซึ่งจะปิดใช้งานการคอมไพล์ AOT ทั้งหมดสำหรับโมดูลนี้ - สำหรับ การแก้ไขบรรทัดคำสั่งส่วนกลางอย่างรวดเร็ว ให้ใช้ตัวแปรสภาพแวดล้อม
RELAX_USES_LIBRARY_CHECK=true
มันมีผลเช่นเดียวกับPRODUCT_BROKEN_VERIFY_USES_LIBRARIES
แต่มีไว้สำหรับใช้ในบรรทัดคำสั่ง ตัวแปรสภาพแวดล้อมจะแทนที่ตัวแปรผลิตภัณฑ์ - สำหรับวิธีแก้ปัญหาที่ ต้นเหตุ แก้ไข ข้อผิดพลาด ให้ทำให้ระบบบิลด์ทราบถึงแท็ก
<uses-library>
ในรายการ การตรวจสอบข้อความแสดงข้อผิดพลาดจะแสดงว่าไลบรารีใดที่ทำให้เกิดปัญหา (เช่นเดียวกับการตรวจสอบAndroidManifest.xml
หรือรายการภายใน APK ที่สามารถตรวจสอบได้ด้วย `aapt dump badging $APK | grep uses-library
`)
สำหรับโมดูล Android.bp
:
ค้นหาไลบรารีที่หายไปในคุณสมบัติ
libs
ของโมดูล หากมีอยู่แล้ว Soong มักจะเพิ่มไลบรารีดังกล่าวโดยอัตโนมัติ ยกเว้นในกรณีพิเศษเหล่านี้:- ไลบรารีนี้ไม่ใช่ไลบรารี SDK (ถูกกำหนดเป็น
java_library
แทนที่จะเป็นjava_sdk_library
) - ไลบรารีมีชื่อไลบรารีที่แตกต่างจาก (ในรายการ) จากชื่อโมดูล (ในระบบบิลด์)
หากต้องการแก้ไขปัญหานี้ชั่วคราว ให้เพิ่ม
provides_uses_lib: "<library-name>"
ในคำจำกัดความของไลบรารีAndroid.bp
สำหรับวิธีแก้ปัญหาระยะยาว ให้แก้ไขปัญหาที่ซ่อนอยู่: แปลงไลบรารีเป็นไลบรารี SDK หรือเปลี่ยนชื่อโมดูล- ไลบรารีนี้ไม่ใช่ไลบรารี SDK (ถูกกำหนดเป็น
หากขั้นตอนก่อนหน้านี้ไม่ได้ระบุวิธีแก้ปัญหา ให้เพิ่ม
uses_libs: ["<library-module-name>"]
สำหรับไลบรารีที่จำเป็น หรือoptional_uses_libs: ["<library-module-name>"]
สำหรับไลบรารีเสริมสำหรับAndroid.bp
คำจำกัดความAndroid.bp
ของโมดูล คุณสมบัติเหล่านี้ยอมรับรายการชื่อโมดูล ลำดับสัมพัทธ์ของไลบรารีในรายการจะต้องเหมือนกับลำดับในรายการ
สำหรับโมดูล Android.mk
:
ตรวจสอบว่าไลบรารีมีชื่อไลบรารีอื่น (ในรายการ) จากชื่อโมดูล (ในระบบ build) หรือไม่ หากเป็นเช่นนั้น ให้แก้ไขปัญหานี้ชั่วคราวโดยเพิ่ม
LOCAL_PROVIDES_USES_LIBRARY := <library-name>
ในไฟล์Android.mk
ของไลบรารี หรือเพิ่มprovides_uses_lib: "<library-name>"
ในไฟล์Android.bp
ของไลบรารี (ทั้งสองกรณี เป็นไปได้เนื่องจากโมดูลAndroid.mk
อาจขึ้นอยู่กับไลบรารีAndroid.bp
) สำหรับวิธีแก้ปัญหาระยะยาว ให้แก้ไขปัญหาพื้นฐาน: เปลี่ยนชื่อโมดูลไลบรารีเพิ่ม
LOCAL_USES_LIBRARIES := <library-module-name>
สำหรับไลบรารีที่จำเป็น เพิ่มLOCAL_OPTIONAL_USES_LIBRARIES := <library-module-name>
สำหรับไลบรารีเสริมให้กับคำจำกัดความAndroid.mk
ของโมดูล คุณสมบัติเหล่านี้ยอมรับรายการชื่อโมดูล ลำดับสัมพัทธ์ของไลบรารีในรายการจะต้องเหมือนกันกับในรายการ
ข้อผิดพลาดของบิลด์: เส้นทางไลบรารีที่ไม่รู้จัก
หากระบบบิลด์ไม่พบเส้นทางไปยัง <uses-library>
DEX jar (ไม่ว่าจะเป็นเส้นทางเวลาบิลด์บนโฮสต์หรือเส้นทางการติดตั้งบนอุปกรณ์) ก็มักจะล้มเหลวในการสร้าง ความล้มเหลวในการค้นหาเส้นทางอาจบ่งชี้ว่ามีการกำหนดค่าไลบรารีด้วยวิธีที่ไม่คาดคิด แก้ไขบิลด์ชั่วคราวโดยการปิดใช้งาน dexpreopt สำหรับโมดูลที่มีปัญหา
Android.bp (คุณสมบัติของโมดูล):
enforce_uses_libs: false,
dex_preopt: {
enabled: false,
},
Android.mk (ตัวแปรโมดูล):
LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_DEX_PREOPT := false
แจ้งจุดบกพร่องเพื่อตรวจสอบสถานการณ์ที่ไม่รองรับ
ข้อผิดพลาดของบิลด์: ขาดการพึ่งพาไลบรารี
ความพยายามในการเพิ่ม <uses-library>
X จากรายการของโมดูล Y ไปยังไฟล์บิลด์สำหรับ Y อาจส่งผลให้เกิดข้อผิดพลาดของบิลด์เนื่องจากการพึ่งพาที่ขาดหายไป X
นี่เป็นข้อความแสดงข้อผิดพลาดตัวอย่างสำหรับโมดูล Android.bp:
"Y" depends on undefined module "X"
นี่เป็นข้อความแสดงข้อผิดพลาดตัวอย่างสำหรับโมดูล Android.mk:
'.../JAVA_LIBRARIES/com.android.X_intermediates/dexpreopt.config', needed by '.../APPS/Y_intermediates/enforce_uses_libraries.status', missing and no known rule to make it
สาเหตุทั่วไปของข้อผิดพลาดดังกล่าวคือเมื่อมีการตั้งชื่อไลบรารีแตกต่างจากการตั้งชื่อโมดูลที่เกี่ยวข้องในระบบบิลด์ ตัวอย่างเช่น หากรายการ <uses-library>
ของรายการคือ com.android.X
แต่ชื่อของโมดูลไลบรารีเป็นเพียง X
ก็ทำให้เกิดข้อผิดพลาดได้ เพื่อแก้ไขปัญหานี้ ให้แจ้งระบบบิลด์ว่าโมดูลชื่อ X
จัดเตรียม <uses-library>
ชื่อ com.android.X
นี่คือตัวอย่างสำหรับไลบรารี Android.bp
(คุณสมบัติของโมดูล):
provides_uses_lib: “com.android.X”,
นี่คือตัวอย่างสำหรับไลบรารี Android.mk (ตัวแปรโมดูล):
LOCAL_PROVIDES_USES_LIBRARY := com.android.X
CLC เวลาบูตไม่ตรงกัน
เมื่อบูตครั้งแรก ให้ค้นหา logcat เพื่อหาข้อความที่เกี่ยวข้องกับ CLC ที่ไม่ตรงกัน ดังที่แสดงด้านล่าง:
$ adb wait-for-device && adb logcat \
| grep -E 'ClassLoaderContext [a-z ]+ mismatch' -A1
ผลลัพธ์สามารถมีข้อความของแบบฟอร์มที่แสดงไว้ที่นี่:
[...] W system_server: ClassLoaderContext shared library size mismatch Expected=..., found=... (PCL[]... | PCL[]...)
[...] I PackageDexOptimizer: Running dexopt (dexoptNeeded=1) on: ...
หากคุณได้รับคำเตือน CLC ไม่ตรงกัน ให้มองหาคำสั่ง dexopt สำหรับโมดูลที่ผิดพลาด ในการแก้ไข ตรวจสอบให้แน่ใจว่าการตรวจสอบเวลาการสร้างสำหรับโมดูลผ่านไปแล้ว หากไม่ได้ผล แสดงว่าของคุณอาจเป็นกรณีพิเศษที่ระบบบิวด์ไม่รองรับ (เช่น แอปที่โหลด APK อื่น ไม่ใช่ไลบรารี) ระบบบิลด์ไม่ได้รองรับทุกกรณี เนื่องจากในขณะสร้าง เป็นไปไม่ได้ที่จะทราบแน่ชัดว่าแอปโหลดอะไรในขณะรันไทม์
บริบทตัวโหลดคลาส
CLC เป็นโครงสร้างแบบต้นไม้ที่อธิบายลำดับชั้นของคลาสโหลดเดอร์ ระบบบิลด์ใช้ CLC ในแง่แคบ (ครอบคลุมเฉพาะไลบรารี ไม่ใช่ APK หรือตัวโหลดคลาสที่กำหนดเอง): เป็นแผนผังของไลบรารีที่แสดงถึงการปิดแบบสกรรมกริยาของการขึ้นต่อกันของ <uses-library>
ทั้งหมดของไลบรารีหรือแอป องค์ประกอบระดับบนสุดของ CLC คือการพึ่งพา <uses-library>
โดยตรงที่ระบุในรายการ (classpath) แต่ละโหนดของแผนผัง CLC คือโหนด <uses-library>
ที่อาจมีโหนดย่อย <uses-library>
ของตัวเอง
เนื่องจากการขึ้นต่อกันของ <uses-library>
เป็นกราฟอะไซคลิกโดยตรง และไม่จำเป็นต้องเป็นแผนผัง CLC จึงสามารถมีทรีย่อยหลายรายการสำหรับไลบรารีเดียวกันได้ กล่าวอีกนัยหนึ่ง CLC คือกราฟการขึ้นต่อกันที่ "กางออก" ไปยังแผนผัง การทำสำเนาอยู่ในระดับตรรกะเท่านั้น ตัวโหลดคลาสพื้นฐานที่แท้จริงจะไม่ถูกทำซ้ำ (ที่รันไทม์จะมีอินสแตนซ์ตัวโหลดคลาสตัวเดียวสำหรับแต่ละไลบรารี)
CLC กำหนดลำดับการค้นหาของไลบรารีเมื่อแก้ไขคลาส Java ที่ใช้โดยไลบรารีหรือแอป ลำดับการค้นหามีความสำคัญเนื่องจากไลบรารีสามารถมีคลาสที่ซ้ำกัน และคลาสได้รับการแก้ไขให้ตรงกับคลาสแรก
CLC บนอุปกรณ์ (รันไทม์)
PackageManager
(ใน frameworks/base
) สร้าง CLC เพื่อโหลดโมดูล Java บนอุปกรณ์ โดยจะเพิ่มไลบรารีที่อยู่ในแท็ก <uses-library>
ในรายการของโมดูลเป็นองค์ประกอบ CLC ระดับบนสุด
สำหรับไลบรารีที่ใช้แต่ละไลบรารี PackageManager
จะได้รับการอ้างอิง <uses-library>
ทั้งหมด (ระบุเป็นแท็กในรายการของไลบรารีนั้น) และเพิ่ม CLC ที่ซ้อนกันสำหรับการขึ้นต่อกันแต่ละรายการ กระบวนการนี้ดำเนินต่อไปแบบวนซ้ำจนกว่าโหนดปลายสุดของแผนผัง CLC ที่สร้างขึ้นจะเป็นไลบรารีที่ไม่มีการขึ้นต่อกันของ <uses-library>
PackageManager
ทราบเฉพาะไลบรารีที่แบ่งใช้เท่านั้น คำจำกัดความของการแบ่งปันในการใช้งานนี้แตกต่างจากความหมายปกติ (เช่น การแบ่งปัน กับ คงที่) ใน Android ไลบรารีที่แบ่งใช้ของ Java อยู่ในรายการการกำหนดค่า XML ที่ติดตั้งบนอุปกรณ์ ( /system/etc/permissions/platform.xml
) แต่ละรายการประกอบด้วยชื่อของไลบรารีที่แบ่งใช้ เส้นทางไปยังไฟล์ DEX jar และรายการการขึ้นต่อกัน (ไลบรารีที่แบ่งใช้อื่นๆ ที่ไลบรารีนี้ใช้ในรันไทม์ และระบุในแท็ก <uses-library>
ในรายการ)
กล่าวอีกนัยหนึ่ง มีแหล่งข้อมูลสองแหล่งที่อนุญาตให้ PackageManager
สร้าง CLC ณ รันไทม์: แท็ก <uses-library>
ในรายการ และการพึ่งพาไลบรารีที่ใช้ร่วมกันในการกำหนดค่า XML
CLC บนโฮสต์ (เวลาสร้าง)
CLC ไม่จำเป็นเฉพาะเมื่อโหลดไลบรารีหรือแอปเท่านั้น แต่ยังจำเป็นเมื่อคอมไพล์อีกด้วย การคอมไพล์อาจเกิดขึ้นได้ทั้งบนอุปกรณ์ (dexopt) หรือระหว่างการสร้าง (dexpreopt) เนื่องจาก dexopt เกิดขึ้นบนอุปกรณ์ จึงมีข้อมูลเดียวกันกับ PackageManager
(รายการและการขึ้นต่อกันของไลบรารีที่ใช้ร่วมกัน) อย่างไรก็ตาม Dexpreopt เกิดขึ้นบนโฮสต์และในสภาพแวดล้อมที่แตกต่างกันโดยสิ้นเชิง และจะต้องได้รับข้อมูลเดียวกันจากระบบบิลด์
ดังนั้น CLC ในเวลาบิลด์ที่ใช้โดย dexpreopt และ CLC รันไทม์ที่ใช้โดย PackageManager
จึงเป็นสิ่งเดียวกัน แต่คำนวณด้วยสองวิธีที่แตกต่างกัน
CLC เวลาสร้างและรันไทม์ ต้อง ตรงกัน มิฉะนั้นโค้ดที่คอมไพล์ AOT ที่สร้างโดย dexpreopt จะถูกปฏิเสธ ในการตรวจสอบความเท่าเทียมกันของ CLC เวลาบิลด์และรันไทม์ คอมไพเลอร์ dex2oat จะบันทึก CLC เวลาบิลด์ในไฟล์ *.odex
(ในฟิลด์ classpath
ของส่วนหัวของไฟล์ OAT) หากต้องการค้นหา CLC ที่เก็บไว้ ให้ใช้คำสั่งนี้:
oatdump --oat-file=<FILE> | grep '^classpath = '
CLC เวลาบิลด์และเวลารันไทม์ไม่ตรงกันถูกรายงานใน logcat ระหว่างการบู๊ต ค้นหาด้วยคำสั่งนี้:
logcat | grep -E 'ClassLoaderContext [az ]+ mismatch'
ความไม่ตรงกันเป็นผลเสียต่อประสิทธิภาพ เนื่องจากจะบังคับให้ไลบรารีหรือแอปต้อง Dexopted หรือทำงานโดยไม่มีการเพิ่มประสิทธิภาพ (เช่น รหัสของแอปอาจต้องแยกออกจาก APK ในหน่วยความจำ ซึ่งเป็นการดำเนินการที่มีราคาแพงมาก)
ไลบรารีแบบแบ่งใช้อาจเป็นแบบทางเลือกหรือจำเป็นก็ได้ จากจุดยืนของ dexpreopt ต้องมีไลบรารีที่จำเป็นในขณะสร้าง (การขาดหายไปคือข้อผิดพลาดของการสร้าง) ไลบรารีเสริมอาจมีหรือไม่มีในขณะสร้างก็ได้ ถ้ามี ไลบรารีนั้นจะถูกเพิ่มลงใน CLC ส่งผ่านไปยัง dex2oat และบันทึกในไฟล์ *.odex
หากไม่มีไลบรารีเผื่อเลือก ไลบรารีนั้นจะถูกข้ามและจะไม่ถูกเพิ่มลงใน CLC หากมีความไม่ตรงกันระหว่างสถานะเวลาบิลด์และรันไทม์ (มีไลบรารีเผื่อเลือกในกรณีหนึ่ง แต่ไม่มีในกรณีอื่น) แสดงว่า CLC เวลาบิลด์และเวลารันไทม์ไม่ตรงกันและโค้ดที่คอมไพล์แล้วจะถูกปฏิเสธ
รายละเอียดระบบบิลด์ขั้นสูง (ตัวแก้ไขรายการ)
บางครั้งแท็ก <uses-library>
หายไปจากรายการแหล่งที่มาของไลบรารีหรือแอป กรณีนี้อาจเกิดขึ้นได้ เช่น หากหนึ่งในการอ้างอิงแบบสกรรมกริยาของไลบรารีหรือแอปเริ่มใช้แท็ก <uses-library>
อื่น และไลบรารีหรือรายการของแอปไม่ได้รับการอัปเดตเพื่อรวมไว้
Soong สามารถคำนวณแท็ก <uses-library>
ที่หายไปบางส่วนสำหรับไลบรารีหรือแอปที่กำหนดได้โดยอัตโนมัติ เนื่องจากไลบรารี SDK ในการปิดการพึ่งพาแบบสกรรมกริยาของไลบรารีหรือแอป จำเป็นต้องปิดตัวลงเนื่องจากไลบรารี (หรือแอป) อาจขึ้นอยู่กับไลบรารีแบบคงที่ซึ่งขึ้นอยู่กับไลบรารี SDK และอาจต้องอาศัยการส่งผ่านไลบรารีอื่นอีกครั้ง
แท็ก <uses-library>
ทั้งหมดไม่สามารถคำนวณด้วยวิธีนี้ได้ แต่เมื่อเป็นไปได้ ควรปล่อยให้ Soong เพิ่มรายการรายการโดยอัตโนมัติ มีข้อผิดพลาดน้อยกว่าและทำให้การบำรุงรักษาง่ายขึ้น ตัวอย่างเช่น เมื่อแอปจำนวนมากใช้ไลบรารีแบบคงที่ที่เพิ่มการพึ่งพา <uses-library>
ใหม่ แอปทั้งหมดจะต้องได้รับการอัปเดต ซึ่งยากต่อการบำรุงรักษา