ตั้งแต่ Android 17 เป็นต้นไป แอปที่กำหนดเป้าหมายเป็น Android 17
หรือสูงกว่าจะได้รับการใช้งานแบบใหม่ที่ไม่มีการล็อกของ
android.os.MessageQueue การติดตั้งใช้งานใหม่นี้ช่วยปรับปรุงประสิทธิภาพและ
ลดเฟรมที่พลาดไป แต่ก็อาจทำให้ไคลเอ็นต์ที่ใช้ฟิลด์และเมธอดส่วนตัวMessageQueue
ใช้งานไม่ได้
Android 17 ได้ปรับปรุงวิธีที่ Looper และ
Handler ทำงานอย่างมากด้วยการเขียนคลาส MessageQueue พื้นฐานใหม่
ตั้งแต่ระบบปฏิบัติการ Android เวอร์ชันแรก MessageQueue ใช้
ล็อกเดียวเพื่อจัดการคิวงานของเทรดหลัก การออกแบบนี้มัก
ทำให้เกิดการแย่งกันล็อก เทรดหลักอาจถูกบล็อกโดยเทรดในเบื้องหลัง
ซึ่งส่งผลให้เฟรมหลุดและ UI กระตุก
ลดผลกระทบ
แอปของคุณอาจได้รับผลกระทบจากการเปลี่ยนแปลงนี้หากแอปหรือการขึ้นต่อกันของแอปอาศัยการสะท้อนรันไทม์เพื่อดูภายใน MessageQueue หลีกเลี่ยงการใช้การสะท้อนรันไทม์เพื่อตรวจสอบ MessageQueue
การใช้งานแบบเดิมทำให้นักพัฒนาแอปเข้าถึงฟิลด์ส่วนตัวได้ในบางครั้ง
เช่น MessageQueue.mMessages เพื่อตรวจสอบข้อความที่รอดำเนินการ การใช้งานแบบใหม่ที่ไม่มีการล็อกทำให้โครงสร้างข้อมูลภายในมีการเปลี่ยนแปลงโดยสิ้นเชิง
Android 17 จะเก็บฟิลด์ mMessages ไว้เพื่อรักษาความเข้ากันได้ของไบนารี แต่ในการ
ใช้งานใหม่ ฟิลด์นี้จะเป็น null เสมอ ไม่ว่าจะมีข้อความในคิวหรือไม่ก็ตาม
นอกจากนี้ หากคุณใช้ไลบรารีการทดสอบยอดนิยมบางรายการ คุณจะต้องอัปเดตไลบรารีให้เข้ากันได้กับการติดตั้งใช้งาน MessageQueue ใหม่
เอสเพรสโซ
โดยทั่วไป Espresso ใช้สำหรับการทดสอบ UI ไลบรารี Espresso ต้องทราบ เมื่อเทรดหลักไม่ได้ใช้งานเพื่อให้ยืนยันสถานะ UI ได้อย่างถูกต้อง Espresso เวอร์ชันก่อนหน้า ใช้เทคนิคการสะท้อนซึ่งใช้กับ MessageQueue แบบไม่ล็อกไม่ได้อีกต่อไป
การทำงาน
อัปเดตเป็น Espresso 3.7.0 ขึ้นไป เวอร์ชันนี้ใช้ API ของ
TestLooperManager โดยเฉพาะ API ใหม่ที่ Android 16 เปิดตัว
เพื่อโต้ตอบกับ Looper อย่างปลอดภัยโดยไม่ต้องอาศัยรายละเอียดการติดตั้งใช้งานภายใน
Robolectric
ในทำนองเดียวกัน หากคุณเรียกใช้การทดสอบหน่วยโดยใช้ Robolectric คุณอาจพบปัญหาหาก การทดสอบของคุณอาศัยโหมด Looper เดิม
การทำงาน
อัปเดตเป็น Robolectric 4.17 ขึ้นไป หากใช้ @LooperMode(LEGACY)
คุณจะต้องย้ายข้อมูลการทดสอบไปยัง @LooperMode(PAUSED) ใหม่ ดูข้อมูลเพิ่มเติมได้ที่คำแนะนำในการย้ายข้อมูลของ Robolectric
ทดสอบลักษณะการทำงาน
คุณสามารถทดสอบแอปที่มีการเปลี่ยนแปลงลักษณะการทำงานใน Android 17 ได้โดยไม่ต้องอัปเดต
targetSDK โดยเรียกใช้คำสั่งต่อไปนี้
adb am compat enable USE_NEW_MESSAGEQUEUE <your-package-name>
คำสั่งนี้จะเปิดใช้ MessageQueue แบบไม่มีการล็อกในแอป หากเป็นบิลด์ที่แก้ไขข้อบกพร่องได้
หากแอปกำหนดเป้าหมายเป็น Android 17 ระบบจะเปิดใช้ลักษณะการทำงานใหม่โดยค่าเริ่มต้น หากพบลักษณะการทำงานที่ไม่คาดคิดหรือแอปขัดข้องหลังจากกำหนดเป้าหมายระดับ API นี้ คุณสามารถปิดใช้การติดตั้งใช้งานใหม่ชั่วคราวเพื่อตรวจสอบว่า MessageQueue เป็นสาเหตุหรือไม่
คุณสลับการเปลี่ยนแปลงได้โดยใช้ตัวเลือกใดตัวเลือกหนึ่งต่อไปนี้
เมนูการเปลี่ยนแปลงความเข้ากันได้ของแอปในตัวเลือกสำหรับนักพัฒนาแอป
โดยเรียกใช้คำสั่ง ADB ต่อไปนี้
adb am compat disable USE_NEW_MESSAGEQUEUE <your-package-name>
การดำเนินการนี้จะเปลี่ยนแอปกลับไปใช้การติดตั้งใช้งานแบบเดิมที่อิงตามการล็อก ซึ่งจะช่วยให้คุณ ระบุได้ว่าปัญหาเกิดจากการเปลี่ยนแปลงลักษณะการทำงานของคิวข้อความหรือไม่