ตั้งแต่ Android 17 เป็นต้นไป แอปที่กำหนดเป้าหมายเป็น Android 17 (API ระดับ 37) ขึ้นไปจะได้รับการติดตั้งใช้งาน android.os.MessageQueue แบบไม่มีการล็อกใหม่ การติดตั้งใช้งานใหม่จะช่วยปรับปรุงประสิทธิภาพและลดเฟรมที่ขาดหายไป แต่อาจทำให้ไคลเอ็นต์ที่แสดงผลในฟิลด์และเมธอดส่วนตัวของ MessageQueue เสียหาย
Android 17 มีการปรับปรุงครั้งใหญ่เกี่ยวกับวิธีการทำงานของ Looper และ Handler โดยการเขียนคลาส MessageQueue ที่สำคัญใหม่
ตั้งแต่การเปิดตัวระบบปฏิบัติการ Android เวอร์ชันแรก MessageQueue อาศัยการล็อกเดียวเพื่อจัดการคิวงานของเทรดหลัก การออกแบบนี้มักทำให้เกิดการแย่งชิงล็อก โดยเทรดหลักอาจถูกบล็อกโดยเทรดเบื้องหลัง ซึ่งทำให้เฟรมหายไปและ UI กระตุก
ลดผลกระทบ
แอปของคุณอาจได้รับผลกระทบจากการเปลี่ยนแปลงนี้หากแอปหรือทรัพยากร Dependency ของแอปอาศัย Runtime Reflection เพื่อดูภายใน MessageQueue หลีกเลี่ยงการใช้การสะท้อนรันไทม์เพื่อตรวจสอบ MessageQueue
ในการติดตั้งใช้งานแบบเดิม บางครั้งนักพัฒนาแอปจะเข้าถึงช่องส่วนตัว เช่น MessageQueue.mMessages เพื่อตรวจสอบข้อความที่รอดำเนินการ ด้วยการใช้งานแบบไม่มีการล็อกใหม่ โครงสร้างข้อมูลภายในจึงเปลี่ยนไปโดยสิ้นเชิง
Android 17 จะเก็บช่อง mMessages ไว้เพื่อรักษาความเข้ากันได้ของไบนารี แต่ในการติดตั้งใช้งานใหม่ ช่องนี้จะเป็นค่า Null เสมอ ไม่ว่าจะมีข้อความในคิวหรือไม่ก็ตาม
นอกจากนี้ หากใช้ไลบรารีการทดสอบยอดนิยมบางรายการ คุณจะต้องอัปเดตไลบรารีให้เข้ากันได้กับการติดตั้งใช้งาน MessageQueue ใหม่
Espresso
Espresso มักใช้สำหรับการทดสอบ UI ไลบรารี Espresso ต้องทราบว่าเธรดหลักไม่มีการใช้งานเมื่อใดเพื่อยืนยันสถานะ UI อย่างถูกต้อง Espresso เวอร์ชันก่อนหน้าอาศัยเทคนิคการสะท้อนซึ่งไม่สามารถใช้งานร่วมกับ MessageQueue แบบไม่มีการล็อกได้อีกต่อไป
การทำงาน
อัปเดตเป็น Espresso 3.7.0 ขึ้นไป เวอร์ชันนี้ใช้ API TestLooperManager โดยเฉพาะ API ใหม่ที่ Android 16 เปิดตัว เพื่อโต้ตอบกับ Looper อย่างปลอดภัยโดยไม่ต้องอาศัยรายละเอียดการติดตั้งใช้งานภายใน
Robolectric
ในทำนองเดียวกัน หากคุณเรียกใช้ Unit Test โดยใช้ 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 37) ระบบจะเปิดใช้ลักษณะการทำงานใหม่โดยค่าเริ่มต้น หากพบพฤติกรรมที่ไม่คาดคิดหรือข้อขัดข้องหลังจากกำหนดเป้าหมายระดับ API นี้ คุณสามารถปิดใช้การติดตั้งใช้งานใหม่ชั่วคราวเพื่อตรวจสอบว่า MessageQueue เป็นสาเหตุหรือไม่
คุณสลับการเปลี่ยนแปลงได้โดยใช้ตัวเลือกใดตัวเลือกหนึ่งจาก 2 ตัวเลือกต่อไปนี้
เมนูการเปลี่ยนแปลงความเข้ากันได้ของแอปในตัวเลือกสำหรับนักพัฒนาแอป
โดยเรียกใช้คำสั่ง ADB ต่อไปนี้
adb am compat disable USE_NEW_MESSAGEQUEUE <your-package-name>
ซึ่งจะเปลี่ยนแอปกลับไปใช้การติดตั้งใช้งานแบบเดิมที่ใช้การล็อก เพื่อให้คุณระบุได้ว่าปัญหาเกิดจากการเปลี่ยนแปลงลักษณะการทำงานของคิวข้อความหรือไม่