ก่อนเริ่มต้น โปรดดูภาพรวมระดับสูงของบริการ ART
ตั้งแต่ Android 14 เป็นต้นไป การคอมไพล์ AOT ในอุปกรณ์สำหรับแอป (หรือที่เรียกว่า dexopt) จะจัดการโดยบริการ ART บริการ ART เป็นส่วนหนึ่งของข้อบังคับของ ART และคุณสามารถปรับแต่งผ่านพร็อพเพอร์ตี้ของระบบและ API
พร็อพเพอร์ตี้ของระบบ
บริการ ART รองรับตัวเลือก dex2oat ที่เกี่ยวข้องทั้งหมด
นอกจากนี้ บริการ ART ยังรองรับพร็อพเพอร์ตี้ระบบต่อไปนี้ด้วย
pm.dexopt.<reason>
ชุดพร็อพเพอร์ตี้ของระบบนี้จะกำหนดตัวกรองคอมไพเลอร์เริ่มต้นสำหรับเหตุผลในการคอมไพล์ที่กำหนดไว้ล่วงหน้าทั้งหมดที่อธิบายไว้ในสถานการณ์ Dexopt
ดูข้อมูลเพิ่มเติมได้ที่ตัวกรองคอมไพเลอร์
ค่าเริ่มต้นมาตรฐานมีดังนี้
pm.dexopt.first-boot=verify
pm.dexopt.boot-after-ota=verify
pm.dexopt.boot-after-mainline-update=verify
pm.dexopt.bg-dexopt=speed-profile
pm.dexopt.inactive=verify
pm.dexopt.cmdline=verify
pm.dexopt.shared (ค่าเริ่มต้น: speed)
นี่คือตัวกรองคอมไพเลอร์สำรองสําหรับแอปที่แอปอื่นๆ ใช้
โดยหลักการแล้ว บริการ ART จะทำการคอมไพล์โดยอิงตามโปรไฟล์ (speed-profile
) สำหรับแอปทั้งหมดเมื่อเป็นไปได้ ซึ่งโดยปกติจะดำเนินการระหว่างที่ Dexopt ทำงานอยู่เบื้องหลัง อย่างไรก็ตาม แอปบางแอปใช้โดยแอปอื่นๆ (ผ่าน <uses-library>
หรือโหลดแบบไดนามิกโดยใช้ Context#createPackageContext
กับ CONTEXT_INCLUDE_CODE
) แอปดังกล่าวจะใช้โปรไฟล์ในเครื่องไม่ได้เนื่องจากเหตุผลด้านความเป็นส่วนตัว
สําหรับแอปดังกล่าว หากมีการขอการคอมไพล์ที่แนะนําโดยโปรไฟล์ บริการ ART จะพยายามใช้โปรไฟล์ระบบคลาวด์ก่อน หากไม่มีโปรไฟล์ระบบคลาวด์ บริการ ART จะเปลี่ยนไปใช้ตัวกรองคอมไพเลอร์ที่ระบุโดย pm.dexopt.shared
หากการคอมไพล์ที่ขอไม่ได้ใช้โปรไฟล์เป็นแนวทาง พร็อพเพอร์ตี้นี้จะไม่มีผล
pm.dexopt.<reason>.concurrency (ค่าเริ่มต้น: 1)
นี่คือจํานวนการเรียก dex2oat สําหรับเหตุผลบางอย่างในการคอมไพล์ที่กําหนดไว้ล่วงหน้า (first-boot
, boot-after-ota
, boot-after-mainline-update
และ bg-dexopt
)
โปรดทราบว่าผลของตัวเลือกนี้จะรวมกับตัวเลือกการใช้ทรัพยากรของ dex2oat (dalvik.vm.*dex2oat-threads
,
dalvik.vm.*dex2oat-cpu-set
และโปรไฟล์งาน) ดังนี้
dalvik.vm.*dex2oat-threads
ควบคุมจำนวนเธรดสำหรับการเรียกใช้ dex2oat แต่ละครั้ง ส่วนpm.dexopt.<reason>.concurrency
ควบคุมจำนวนการเรียกใช้ dex2oat กล่าวคือ จํานวนเธรดสูงสุดที่ทํางานพร้อมกันคือผลคูณของพร็อพเพอร์ตี้ระบบ 2 รายการdalvik.vm.*dex2oat-cpu-set
และโปรไฟล์งานจะจำกัดการใช้แกน CPU เสมอ โดยไม่คำนึงถึงจำนวนชุดข้อความสูงสุดที่ทำงานพร้อมกัน (ตามที่ได้อธิบายไว้ข้างต้น)
การเรียกใช้ dex2oat ครั้งเดียวอาจไม่ได้ใช้แกน CPU ทั้งหมดอย่างเต็มประสิทธิภาพ ไม่ว่า dalvik.vm.*dex2oat-threads
จะเป็นอย่างไรก็ตาม ดังนั้น การเพิ่มจำนวนการเรียกใช้ dex2oat (pm.dexopt.<reason>.concurrency
) จะช่วยใช้แกน CPU ได้ดียิ่งขึ้น เพื่อเร่งความคืบหน้าโดยรวมของ dexopt ซึ่งจะเป็นประโยชน์อย่างยิ่งในระหว่างการบูต
อย่างไรก็ตาม การเรียกใช้ dex2oat มากเกินไปอาจทำให้อุปกรณ์มีหน่วยความจำไม่เพียงพอ แม้ว่าจะลดปัญหานี้ได้ด้วยการตั้งค่า dalvik.vm.dex2oat-swap
เป็น true
เพื่ออนุญาตให้ใช้ไฟล์สลับ การเรียกใช้มากเกินไปอาจทําให้เกิดการเปลี่ยนไปใช้บริบทที่ไม่จําเป็น ดังนั้น คุณควรปรับตัวเลขนี้อย่างละเอียดทีละผลิตภัณฑ์
pm.dexopt.downgrade_after_inactive_days (ค่าเริ่มต้น: ไม่ได้ตั้งค่า)
หากตั้งค่าตัวเลือกนี้ไว้ บริการ ART จะยกเลิกการเลือกแอปที่ใช้ภายในจำนวนวันที่กำหนดเท่านั้น
นอกจากนี้ หากพื้นที่เก็บข้อมูลเหลือน้อยในระหว่างการจัดทํา Dexopt ในเบื้องหลัง บริการ ART จะลดระดับตัวกรองคอมไพเลอร์ของแอปที่ไม่ได้ใช้งานภายในจำนวนวันที่ระบุล่าสุดเพื่อเพิ่มพื้นที่ว่าง เหตุผลที่คอมไพเลอร์ทำเช่นนี้คือ inactive
และตัวกรองคอมไพเลอร์จะกำหนดโดย pm.dexopt.inactive
เกณฑ์พื้นที่เก็บข้อมูลที่จะทริกเกอร์ฟีเจอร์นี้คือเกณฑ์พื้นที่เก็บข้อมูลเหลือน้อยของเครื่องมือจัดการพื้นที่เก็บข้อมูล (กำหนดค่าได้ผ่านการตั้งค่าส่วนกลาง sys_storage_threshold_percentage
และ sys_storage_threshold_max_bytes
โดยค่าเริ่มต้นคือ 500MB) บวก 500MB
หากคุณปรับแต่งรายการแพ็กเกจผ่าน ArtManagerLocal#setBatchDexoptStartCallback
ระบบจะไม่ดาวน์เกรดแพ็กเกจในรายการที่ BatchDexoptStartCallback
ระบุสำหรับ bg-dexopt
pm.dexopt.disable_bg_dexopt (ค่าเริ่มต้น: false)
การดำเนินการนี้มีไว้เพื่อการทดสอบเท่านั้น ซึ่งจะป้องกันไม่ให้บริการ ART กําหนดเวลางาน bg.dexopt
หากมีการตั้งเวลางาน dexopt ในเบื้องหลังไว้แล้วแต่ยังไม่ได้ทํางาน ตัวเลือกนี้จะไม่มีผล กล่าวคือ งานจะยังคงทำงานต่อไป
ลำดับคำสั่งที่แนะนำเพื่อป้องกันไม่ให้งาน dexopt ทำงานอยู่เบื้องหลังมีดังนี้
setprop pm.dexopt.disable_bg_dexopt true
pm bg-dexopt-job --disable
บรรทัดแรกจะป้องกันไม่ให้กำหนดเวลางาน dexopt ในเบื้องหลัง หากยังไม่ได้กำหนดเวลา บรรทัดที่สองจะยกเลิกการตั้งเวลางาน dexopt เบื้องหลัง หากมีการตั้งเวลาไว้แล้ว และยกเลิกงาน dexopt เบื้องหลังทันทีหากงานดังกล่าวกำลังทำงานอยู่
ART Service API
บริการ ART แสดง Java API สำหรับการปรับเปลี่ยน API เหล่านี้จะกำหนดไว้ใน ArtManagerLocal
ดู Javadoc ใน art/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
สำหรับการใช้งาน (แหล่งที่มาของ Android 14, แหล่งที่มาสำหรับนักพัฒนาซอฟต์แวร์รุ่นที่ยังไม่เผยแพร่)
ArtManagerLocal
เป็น Singleton ที่ LocalManagerRegistry
ถือครอง ฟังก์ชันตัวช่วย com.android.server.pm.DexOptHelper#getArtManagerLocal
ช่วยให้คุณรับค่านั้นได้
import static com.android.server.pm.DexOptHelper.getArtManagerLocal;
API ส่วนใหญ่ต้องใช้อินสแตนซ์ของ PackageManagerLocal.FilteredSnapshot
ซึ่งเก็บข้อมูลของแอปทั้งหมด คุณรับค่านี้ได้โดยเรียกใช้ PackageManagerLocal#withFilteredSnapshot
โดยที่ PackageManagerLocal
ก็เป็น Singleton ที่ LocalManagerRegistry
ถือครองอยู่และรับได้จาก com.android.server.pm.PackageManagerServiceUtils#getPackageManagerLocal
import static com.android.server.pm.PackageManagerServiceUtils.getPackageManagerLocal;
ต่อไปนี้คือกรณีการใช้งานทั่วไปของ API
ทริกเกอร์ dexopt สําหรับแอป
คุณเรียกใช้ dexopt สําหรับแอปใดก็ได้ทุกเมื่อโดยเรียกใช้ ArtManagerLocal#dexoptPackage
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
getArtManagerLocal().dexoptPackage(
snapshot,
"com.google.android.calculator",
new DexoptParams.Builder(ReasonMapping.REASON_INSTALL).build());
}
นอกจากนี้ คุณยังส่งเหตุผล dexopt ของคุณเองได้ด้วย หากทำเช่นนั้น คุณต้องตั้งค่าคลาสที่มีลําดับความสําคัญและตัวกรองคอมไพเลอร์อย่างชัดเจน
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
getArtManagerLocal().dexoptPackage(
snapshot,
"com.google.android.calculator",
new DexoptParams.Builder("my-reason")
.setCompilerFilter("speed-profile")
.setPriorityClass(ArtFlags.PRIORITY_BACKGROUND)
.build());
}
ยกเลิก dexopt
หากการเรียกใช้ dexoptPackage
เริ่มต้นการดำเนินการ คุณสามารถส่งสัญญาณการยกเลิก ซึ่งจะช่วยให้คุณยกเลิกการดำเนินการได้ ซึ่งจะมีประโยชน์เมื่อคุณเรียกใช้ dexopt แบบไม่เป็นไปพร้อมกัน
Executor executor = ...; // Your asynchronous executor here.
var cancellationSignal = new CancellationSignal();
executor.execute(() -> {
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
getArtManagerLocal().dexoptPackage(
snapshot,
"com.google.android.calculator",
new DexoptParams.Builder(ReasonMapping.REASON_INSTALL).build(),
cancellationSignal);
}
});
// When you want to cancel the operation.
cancellationSignal.cancel();
นอกจากนี้ คุณยังยกเลิกการจัดระเบียบ Dex ในเบื้องหลังซึ่งบริการ ART เป็นผู้เริ่มได้ด้วย
getArtManagerLocal().cancelBackgroundDexoptJob();
ดูผลลัพธ์ของ dexopt
หากการดําเนินการเริ่มต้นด้วยการเรียกใช้ dexoptPackage
คุณจะดูผลลัพธ์ได้จากค่าที่แสดงผล
DexoptResult result;
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
result = getArtManagerLocal().dexoptPackage(...);
}
// Process the result here.
...
บริการ ART ยังเริ่มการดำเนินการ dexopt ด้วยตนเองในหลายสถานการณ์ เช่น dexopt ในเบื้องหลัง หากต้องการฟังผลลัพธ์ dexopt ทั้งหมด ไม่ว่าจะเริ่มต้นการดำเนินการโดยการเรียก dexoptPackage
หรือโดยบริการ ART ให้ใช้ ArtManagerLocal#addDexoptDoneCallback
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */,
Runnable::run,
(result) -> {
// Process the result here.
...
});
อาร์กิวเมนต์แรกจะกำหนดว่าจะรวมเฉพาะการอัปเดตไว้ในผลลัพธ์หรือไม่ หากต้องการฟังเฉพาะแพ็กเกจที่อัปเดตโดย dexopt ให้ตั้งค่าเป็น true
อาร์กิวเมนต์ที่ 2 คือผู้ดำเนินการของคอลแบ็ก หากต้องการเรียกใช้การเรียกกลับในเธรดเดียวกับที่ดำเนินการ dexopt ให้ใช้ Runnable::run
หากไม่ต้องการให้การเรียกกลับบล็อก dexopt ให้ใช้ตัวดำเนินการแบบไม่พร้อมกัน
คุณสามารถเพิ่มการเรียกกลับได้หลายรายการ และบริการ ART จะเรียกใช้การเรียกกลับทั้งหมดตามลำดับ การติดต่อกลับทั้งหมดจะยังคงทำงานอยู่สำหรับการโทรในอนาคตทั้งหมด เว้นแต่คุณจะนำออก
หากต้องการนําการเรียกกลับออก ให้เก็บข้อมูลอ้างอิงของการเรียกกลับไว้เมื่อเพิ่ม และใช้สําหรับ ArtManagerLocal#removeDexoptDoneCallback
DexoptDoneCallback callback = (result) -> {
// Process the result here.
...
};
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */, Runnable::run, callback);
// When you want to remove it.
getArtManagerLocal().removeDexoptDoneCallback(callback);
ปรับแต่งรายการแพ็กเกจและพารามิเตอร์ dexopt
บริการ ART จะเริ่มต้นการดำเนินการ dexopt ด้วยตนเองระหว่างการบูตและ dexopt เบื้องหลัง หากต้องการปรับแต่งรายการแพ็กเกจหรือพารามิเตอร์ dexopt สำหรับการดำเนินการเหล่านั้น ให้ใช้ ArtManagerLocal#setBatchDexoptStartCallback
getArtManagerLocal().setBatchDexoptStartCallback(
Runnable::run,
(snapshot, reason, defaultPackages, builder, cancellationSignal) -> {
switch (reason) {
case ReasonMapping.REASON_BG_DEXOPT:
var myPackages = new ArrayList<String>(defaultPackages);
myPackages.add(...);
myPackages.remove(...);
myPackages.sort(...);
builder.setPackages(myPackages);
break;
default:
// Ignore unknown reasons.
}
});
คุณสามารถเพิ่มรายการลงในรายการแพ็กเกจ นำรายการออกจากรายการ จัดเรียงรายการ หรือแม้แต่ใช้รายการอื่นโดยสิ้นเชิง
การโทรกลับต้องไม่สนใจเหตุผลที่ไม่รู้จัก เนื่องจากอาจมีการเพิ่มเหตุผลอื่นๆ ในอนาคต
คุณตั้งค่า BatchDexoptStartCallback
ได้สูงสุด 1 รายการ การโทรกลับจะยังคงทำงานอยู่สำหรับการโทรทั้งหมดในอนาคต เว้นแต่คุณจะล้างข้อมูล
หากต้องการล้างการโทรกลับ ให้ใช้ ArtManagerLocal#clearBatchDexoptStartCallback
getArtManagerLocal().clearBatchDexoptStartCallback();
ปรับแต่งพารามิเตอร์ของงาน dexopt เบื้องหลัง
โดยค่าเริ่มต้น งาน dexopt ในเบื้องหลังจะทำงานวันละครั้งเมื่ออุปกรณ์ไม่ได้ใช้งานและกำลังชาร์จ ซึ่งเปลี่ยนแปลงได้โดยใช้
ArtManagerLocal#setScheduleBackgroundDexoptJobCallback
getArtManagerLocal().setScheduleBackgroundDexoptJobCallback(
Runnable::run,
builder -> {
builder.setPeriodic(TimeUnit.DAYS.toMillis(2));
});
คุณตั้งค่า ScheduleBackgroundDexoptJobCallback
ได้สูงสุด 1 รายการ การโทรกลับจะยังคงทำงานอยู่สำหรับการโทรทั้งหมดในอนาคต เว้นแต่คุณจะล้างข้อมูล
หากต้องการล้างการโทรกลับ ให้ใช้ ArtManagerLocal#clearScheduleBackgroundDexoptJobCallback
getArtManagerLocal().clearScheduleBackgroundDexoptJobCallback();
ปิดใช้ dexopt ชั่วคราว
การดำเนินการ dexopt ที่เริ่มต้นโดยบริการ ART จะทริกเกอร์ BatchDexoptStartCallback
คุณสามารถยกเลิกการดำเนินการเพื่อปิดใช้ dexopt ได้อย่างมีประสิทธิภาพ
หากการดำเนินการที่คุณยกเลิกคือการแยกไฟล์ Dex เบื้องหลัง ระบบจะดำเนินการตามนโยบายการลองอีกครั้งเริ่มต้น (30 วินาที เพิ่มแบบทวีคูณ โดยจำกัดสูงสุดที่ 5 ชั่วโมง)
// Good example.
var shouldDisableDexopt = new AtomicBoolean(false);
getArtManagerLocal().setBatchDexoptStartCallback(
Runnable::run,
(snapshot, reason, defaultPackages, builder, cancellationSignal) -> {
if (shouldDisableDexopt.get()) {
cancellationSignal.cancel();
}
});
// Disable dexopt.
shouldDisableDexopt.set(true);
getArtManagerLocal().cancelBackgroundDexoptJob();
// Re-enable dexopt.
shouldDisableDexopt.set(false);
คุณมี BatchDexoptStartCallback
ได้สูงสุด 1 รายการ หากต้องการใช้ BatchDexoptStartCallback
เพื่อปรับแต่งรายการแพ็กเกจหรือพารามิเตอร์ dexopt ด้วย คุณต้องรวมโค้ดเข้าด้วยกันเป็นคอลแบ็กเดียว
// Bad example.
// Disable dexopt.
getArtManagerLocal().unscheduleBackgroundDexoptJob();
// Re-enable dexopt.
getArtManagerLocal().scheduleBackgroundDexoptJob();
การดำเนินการ dexopt ที่ดำเนินการกับการติดตั้งแอปนั้นไม่ได้เริ่มต้นโดย ART Service แต่จะเป็นผู้จัดการแพ็กเกจที่เริ่มต้นผ่านคําเรียก dexoptPackage
ดังนั้นจึงไม่ทริกเกอร์
BatchDexoptStartCallback
หากต้องการปิดใช้ dexopt เมื่อติดตั้งแอป ให้ป้องกันไม่ให้เครื่องมือจัดการแพ็กเกจเรียกใช้ dexoptPackage
ลบล้างตัวกรองคอมไพเลอร์สำหรับบางแพ็กเกจ (Android 15 ขึ้นไป)
คุณสามารถลบล้างตัวกรองคอมไพเลอร์สำหรับบางแพ็กเกจได้โดยลงทะเบียนการเรียกกลับผ่าน setAdjustCompilerFilterCallback
ระบบจะเรียกใช้การเรียกกลับทุกครั้งที่ระบบจะถอดส่วน Dex ของแพ็กเกจ ไม่ว่าจะมีการเรียกใช้การถอดส่วน Dex โดยบริการ ART ระหว่างการบูตและการถอดส่วน Dex เบื้องหลัง หรือโดยการเรียกใช้ dexoptPackage
API
หากแพ็กเกจไม่จําเป็นต้องปรับเปลี่ยน ฟังก์ชันการเรียกกลับต้องแสดงผลเป็น originalCompilerFilter
getArtManagerLocal().setAdjustCompilerFilterCallback(
Runnable::run,
(packageName, originalCompilerFilter, reason) -> {
if (isVeryImportantPackage(packageName)) {
return "speed-profile";
}
return originalCompilerFilter;
});
คุณตั้งค่า AdjustCompilerFilterCallback
ได้เพียงรายการเดียว หากต้องการใช้ AdjustCompilerFilterCallback
เพื่อลบล้างตัวกรองคอมไพเลอร์สำหรับแพ็กเกจหลายรายการ คุณต้องรวมโค้ดไว้ในการเรียกกลับรายการเดียว การโทรกลับจะยังคงทำงานอยู่สำหรับการโทรทั้งหมดในอนาคต เว้นแต่คุณจะล้างข้อมูล
หากต้องการล้างการโทรกลับ ให้ใช้ ArtManagerLocal#clearAdjustCompilerFilterCallback
getArtManagerLocal().clearAdjustCompilerFilterCallback();
การปรับแต่งอื่นๆ
บริการ ART ยังรองรับการปรับแต่งอื่นๆ บางอย่างด้วย
ตั้งค่าเกณฑ์ความร้อนสำหรับการเพิ่มประสิทธิภาพ Dex ในเบื้องหลัง
ตัวจัดตารางงานจะควบคุมความร้อนของงาน dexopt ในเบื้องหลัง
ระบบจะยกเลิกงานทันทีเมื่ออุณหภูมิถึง THERMAL_STATUS_MODERATE
เกณฑ์ของ THERMAL_STATUS_MODERATE
สามารถปรับได้
ตรวจสอบว่า dexopt เบื้องหลังทำงานอยู่หรือไม่
งาน dexopt ในเบื้องหลังได้รับการจัดการโดยตัวจัดตารางงาน และรหัสงานคือ 27873780
หากต้องการตรวจสอบว่างานทํางานอยู่หรือไม่ ให้ใช้ Job Scheduler API
// Good example.
var jobScheduler =
Objects.requireNonNull(mContext.getSystemService(JobScheduler.class));
int reason = jobScheduler.getPendingJobReason(27873780);
if (reason == PENDING_JOB_REASON_EXECUTING) {
// Do something when the job is running.
...
}
// Bad example.
var backgroundDexoptRunning = new AtomicBoolean(false);
getArtManagerLocal().setBatchDexoptStartCallback(
Runnable::run,
(snapshot, reason, defaultPackages, builder, cancellationSignal) -> {
if (reason.equals(ReasonMapping.REASON_BG_DEXOPT)) {
backgroundDexoptRunning.set(true);
}
});
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */,
Runnable::run,
(result) -> {
if (result.getReason().equals(ReasonMapping.REASON_BG_DEXOPT)) {
backgroundDexoptRunning.set(false);
}
});
if (backgroundDexoptRunning.get()) {
// Do something when the job is running.
...
}
ระบุโปรไฟล์สำหรับ dexopt
หากต้องการใช้โปรไฟล์เพื่อแนะนำ dexopt ให้วางไฟล์ .prof
หรือไฟล์ .dm
ข้าง APK
ไฟล์ .prof
ต้องเป็นไฟล์โปรไฟล์รูปแบบไบนารี และชื่อไฟล์ต้องเป็นชื่อไฟล์ของ APK + .prof
ตัวอย่างเช่น
base.apk.prof
ชื่อไฟล์ .dm
ต้องเป็นชื่อไฟล์ APK ที่มีนามสกุลเป็น .dm
ตัวอย่างเช่น
base.dm
หากต้องการยืนยันว่ามีการใช้โปรไฟล์สำหรับ dexopt ให้เรียกใช้ dexopt พร้อม speed-profile
แล้วตรวจสอบผลลัพธ์
pm art clear-app-profiles <package-name>
pm compile -m speed-profile -f -v <package-name>
บรรทัดแรกจะล้างโปรไฟล์ทั้งหมดที่รันไทม์สร้างขึ้น (เช่น โปรไฟล์ใน /data/misc/profiles
) หากมี เพื่อให้แน่ใจว่าโปรไฟล์ข้าง APK เป็นโปรไฟล์เดียวที่ ART Service สามารถใช้ได้ บรรทัดที่สองจะเรียกใช้ dexopt ด้วย speed-profile
และส่ง -v
เพื่อพิมพ์ผลลัพธ์แบบละเอียด
หากมีการใช้โปรไฟล์ คุณจะเห็น actualCompilerFilter=speed-profile
ในผลการค้นหา ไม่เช่นนั้น คุณจะเห็น actualCompilerFilter=verify
ตัวอย่างเช่น
DexContainerFileDexoptResult{dexContainerFile=/data/app/~~QR0fTV0UbDbIP1Su7XzyPg==/com.google.android.gms-LvusF2uARKOtBbcaPHdUtQ==/base.apk, primaryAbi=true, abi=x86_64, actualCompilerFilter=speed-profile, status=PERFORMED, dex2oatWallTimeMillis=4549, dex2oatCpuTimeMillis=14550, sizeBytes=3715344, sizeBeforeBytes=3715344}
สาเหตุทั่วไปที่บริการ ART ไม่ใช้โปรไฟล์มีดังนี้
- โปรไฟล์มีชื่อไฟล์ไม่ถูกต้องหรือไม่อยู่ข้าง APK
- โปรไฟล์อยู่ในรูปแบบที่ไม่ถูกต้อง
- โปรไฟล์ไม่ตรงกับ APK (Checksum ในโปรไฟล์ไม่ตรงกับ checksum ของไฟล์
.dex
ใน APK)