การเปลี่ยนแปลงลักษณะการทำงาน: แอปที่กำหนดเป้าหมายเป็น API เวอร์ชัน 29 ขึ้นไป

Android 10 มีการเปลี่ยนแปลงลักษณะการทํางานของระบบที่อัปเดตแล้วซึ่งอาจส่งผลต่อแอปของคุณ การเปลี่ยนแปลงที่แสดงในหน้านี้มีผลกับแอปที่กําหนดเป้าหมายเป็น API ระดับ 29 ขึ้นไปเท่านั้น หากแอปตั้งค่า targetSdkVersion เป็น "29" ขึ้นไป คุณควรแก้ไขแอปให้รองรับลักษณะการทำงานเหล่านี้อย่างเหมาะสม หากมี

โปรดตรวจสอบรายการการเปลี่ยนแปลงลักษณะการทำงานที่ส่งผลต่อแอปทั้งหมดที่ทำงานใน Android 10 ด้วย

หมายเหตุ: นอกเหนือจากการเปลี่ยนแปลงที่ระบุไว้ในหน้านี้แล้ว Android 10 ยังมีการเปลี่ยนแปลงและข้อจำกัดด้านความเป็นส่วนตัวจำนวนมาก ซึ่งรวมถึงการเปลี่ยนแปลงต่อไปนี้

  • พื้นที่เก็บข้อมูลที่กำหนดขอบเขต
  • สิทธิ์เข้าถึงหมายเลขซีเรียลของอุปกรณ์ USB
  • ความสามารถในการเปิดใช้ ปิดใช้ และกำหนดค่า Wi-Fi
  • สิทธิ์เข้าถึงตําแหน่งสําหรับ API การเชื่อมต่อ

การเปลี่ยนแปลงเหล่านี้จะส่งผลต่อแอปที่กำหนดเป้าหมายเป็น API ระดับ 29 ขึ้นไป ซึ่งจะช่วยปรับปรุงความเป็นส่วนตัวของผู้ใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีรองรับการเปลี่ยนแปลงเหล่านี้ได้ที่หน้าการเปลี่ยนแปลงด้านความเป็นส่วนตัว

การอัปเดตข้อจํากัดของอินเทอร์เฟซที่ไม่ใช่ SDK

แพลตฟอร์มเริ่มจำกัดอินเทอร์เฟซที่ไม่ใช่ SDK ที่แอปของคุณใช้ได้ใน Android 9 (API ระดับ 28) เพื่อช่วยดูแลความเสถียรและความเข้ากันได้ของแอป Android 10 มีรายการอินเทอร์เฟซที่ไม่ใช่ SDK ซึ่งถูกจํากัดซึ่งอัปเดตแล้วโดยอิงตามการทำงานร่วมกันกับนักพัฒนาแอป Android และการทดสอบภายในครั้งล่าสุด เป้าหมายของเราคือการตรวจสอบว่าอินเทอร์เฟซทางเลือกสาธารณะพร้อมใช้งานแล้วก่อนที่จะจำกัดอินเทอร์เฟซที่ไม่ใช่ SDK

หากคุณจะไม่กำหนดเป้าหมายเป็น Android 10 (API ระดับ 29) การเปลี่ยนแปลงบางอย่างเหล่านี้อาจไม่ส่งผลต่อคุณในทันที อย่างไรก็ตาม แม้ว่าปัจจุบันคุณจะใช้อินเทอร์เฟซที่ไม่ใช่ SDK บางรายการได้ (ขึ้นอยู่กับระดับ API เป้าหมายของแอป) แต่การใช้เมธอดหรือฟิลด์ที่ไม่ใช่ SDK นั้นมักมีความเสี่ยงสูงที่จะทำให้แอปขัดข้อง

หากไม่แน่ใจว่าแอปใช้อินเทอร์เฟซที่ไม่ใช่ SDK หรือไม่ คุณสามารถทดสอบแอปเพื่อดูข้อมูลดังกล่าว หากแอปใช้อินเทอร์เฟซที่ไม่ใช่ SDK คุณควรเริ่มวางแผนการย้ายข้อมูลไปยัง SDK ทางเลือก อย่างไรก็ตาม เราเข้าใจว่าแอปบางแอปมี Use Case ที่ถูกต้องในการใช้อินเทอร์เฟซที่ไม่ใช่ SDK หากไม่พบวิธีอื่นแทนการใช้อินเทอร์เฟซที่ไม่ใช่ SDK สำหรับฟีเจอร์ในแอป คุณควรขอ API สาธารณะใหม่

ดูข้อมูลเพิ่มเติมได้ที่การอัปเดตข้อจำกัดเกี่ยวกับอินเทอร์เฟซที่ไม่ใช่ SDK ใน Android 10 และข้อจำกัดเกี่ยวกับอินเทอร์เฟซที่ไม่ใช่ SDK

หน่วยความจำที่แชร์

Ashmem ได้เปลี่ยนรูปแบบของแผนที่ Dalvik ใน /proc/<pid>/maps ซึ่งส่งผลต่อแอปที่แยกวิเคราะห์ไฟล์แผนที่โดยตรง นักพัฒนาแอปพลิเคชันควรทดสอบรูปแบบ /proc/<pid>/maps ในอุปกรณ์ที่ใช้ Android 10 ขึ้นไป และแยกวิเคราะห์ตามความเหมาะสมหากแอปใช้รูปแบบแผนที่ Dalvik

แอปที่กำหนดเป้าหมายเป็น Android 10 จะใช้ ashmem (/dev/ashmem) โดยตรงไม่ได้ และต้องเข้าถึงหน่วยความจำที่แชร์ผ่านคลาส ASharedMemory ของ NDK แทน นอกจากนี้ แอปไม่สามารถทำ IOCTL โดยตรงกับตัวระบุไฟล์ ashmem ที่มีอยู่ และต้องใช้คลาส ASharedMemory ของ NDK หรือ Android Java API ในการสร้างภูมิภาคหน่วยความจำที่ใช้ร่วมกันแทน การเปลี่ยนแปลงนี้ช่วยเพิ่มความปลอดภัยและความเสถียรเมื่อทำงานกับหน่วยความจำที่ใช้ร่วมกัน ซึ่งจะปรับปรุงประสิทธิภาพและความปลอดภัยของ Android โดยรวม

นำสิทธิ์การเรียกใช้ออกสำหรับไดเรกทอรีหลักของแอป

การดำเนินการกับไฟล์จากไดเรกทอรีหลักของแอปที่เขียนได้ถือเป็นการละเมิด W^X แอปควรโหลดเฉพาะโค้ดไบนารีที่ฝังอยู่ในไฟล์ APK ของแอป

แอปที่ไม่น่าเชื่อถือซึ่งกำหนดเป้าหมายเป็น Android 10 จะเรียกใช้ execve() ในไฟล์ภายในไดเรกทอรีหลักของแอปโดยตรงไม่ได้

นอกจากนี้ แอปที่กำหนดเป้าหมายเป็น Android 10 จะแก้ไขโค้ดที่เรียกใช้งานได้จากไฟล์ที่เปิดด้วย dlopen() ในหน่วยความจำไม่ได้ และไม่สามารถคาดหวังให้ระบบเขียนการเปลี่ยนแปลงเหล่านั้นลงในดิสก์ได้ เนื่องจากระบบไม่สามารถแมปไลบรารี PROT_EXEC ผ่านตัวระบุไฟล์ที่เขียนได้ ซึ่งรวมถึงไฟล์ออบเจ็กต์ที่แชร์ (.so) ที่มีการเปลี่ยนตำแหน่งข้อความ

รันไทม์ Android ยอมรับเฉพาะไฟล์ OAT ที่ระบบสร้างขึ้น

Android Runtime (ART) ไม่เรียกใช้ dex2oat จากกระบวนการแอปพลิเคชันอีกต่อไป การเปลี่ยนแปลงนี้หมายความว่า ART จะยอมรับเฉพาะไฟล์ OAT ที่ระบบสร้างขึ้นเท่านั้น

การบังคับใช้ความถูกต้องของ AOT ใน ART

ก่อนหน้านี้ การคอมไพล์ล่วงหน้า (AOT) ที่ดำเนินการโดยรันไทม์ Android (ART) อาจทําให้รันไทม์ขัดข้องหากสภาพแวดล้อม classpath ไม่เหมือนกัน ณ เวลาคอมไพล์และรันไทม์ Android 10 ขึ้นไปกำหนดให้บริบทสภาพแวดล้อมเหล่านี้เหมือนกันเสมอ ซึ่งส่งผลให้มีการเปลี่ยนแปลงต่อไปนี้ในลักษณะการทํางาน

  • ตัวแโหลดคลาสที่กําหนดเอง ซึ่งก็คือตัวแโหลดคลาสที่เขียนโดยแอป ซึ่งแตกต่างจากตัวแโหลดคลาสจากแพ็กเกจ dalvik.system จะไม่ได้รับการคอมไพล์ AOT เนื่องจาก ART ไม่ทราบเกี่ยวกับการใช้งานการค้นหาคลาสที่กําหนดเองที่รันไทม์
  • ไฟล์ DEX รอง ซึ่งก็คือไฟล์ DEX ที่โหลดโดยแอปที่ไม่ได้อยู่ใน APK หลักด้วยตนเอง ระบบจะคอมไพล์แบบ AOT ในเบื้องหลัง เนื่องจากการคอมไพล์การใช้งานครั้งแรกอาจมีค่าใช้จ่ายสูงเกินไป ซึ่งจะทำให้เกิดเวลาในการตอบสนองที่ไม่ต้องการก่อนการเรียกใช้ โปรดทราบว่าสำหรับแอป เราขอแนะนำให้ใช้การแยกและเลิกใช้ไฟล์ Dex รอง
  • ไลบรารีที่แชร์ใน Android (รายการ <library> และ <uses-library> ในไฟล์ Manifest ของ Android) จะใช้ลําดับชั้นของ Class Loader แตกต่างจากที่ใช้ในแพลตฟอร์มเวอร์ชันก่อนหน้า

การเปลี่ยนแปลงสิทธิ์สําหรับ Intent แบบเต็มหน้าจอ

แอปที่กําหนดเป้าหมายเป็น Android 10 ขึ้นไปและใช้การแจ้งเตือนที่มีIntent แบบเต็มหน้าจอต้องขอสิทธิ์ USE_FULL_SCREEN_INTENT ในไฟล์ Manifest ของแอป นี่เป็นสิทธิ์ปกติ ดังนั้นระบบจึงให้สิทธิ์แก่แอปที่ขอโดยอัตโนมัติ

หากแอปที่กำหนดเป้าหมายเป็น Android 10 ขึ้นไปพยายามสร้างการแจ้งเตือนด้วย Intent แบบเต็มหน้าจอโดยไม่ขอสิทธิ์ที่จำเป็น ระบบจะไม่สนใจ Intent แบบเต็มหน้าจอและแสดงข้อความบันทึกต่อไปนี้

Package your-package-name: Use of fullScreenIntent requires the USE_FULL_SCREEN_INTENT permission

การรองรับอุปกรณ์แบบพับได้

Android 10 มีการเปลี่ยนแปลงที่รองรับอุปกรณ์แบบพับได้และอุปกรณ์หน้าจอขนาดใหญ่

เมื่อแอปทำงานใน Android 10 วิธี onResume() และ onPause() จะทำงานแตกต่างกัน เมื่อแอปหลายแอปปรากฏขึ้นพร้อมกันในโหมดหลายหน้าต่างหรือโหมดหลายจอ กิจกรรมด้านบนทั้งหมดที่โฟกัสได้จะอยู่ในกองที่มองเห็นได้และอยู่ในสถานะ "กลับมาทำงานอีกครั้ง" แต่จะมีเพียงกิจกรรมเดียวที่โฟกัสได้ ซึ่งก็คือกิจกรรม "กลับมาทำงานอีกครั้ง" ด้านบนสุด เมื่อใช้กับเวอร์ชันที่เก่ากว่า Android 10 ระบบจะกลับมาทำงานต่อได้เพียงกิจกรรมเดียวในระบบในแต่ละครั้ง โดยกิจกรรมอื่นๆ ที่มองเห็นได้ทั้งหมดจะหยุดชั่วคราว

อย่าสับสนระหว่าง "โฟกัส" กับกิจกรรม "ที่กลับมาทำงานต่อบนสุด" ระบบจะกําหนดลําดับความสําคัญให้กับกิจกรรมตามลําดับ z เพื่อให้ความสําคัญสูงกว่ากิจกรรมที่ผู้ใช้โต้ตอบด้วยล่าสุด กิจกรรมสามารถกลับมาทำงานที่ด้านบนได้ แต่ไม่ได้รับการโฟกัส (เช่น หากแผงการแจ้งเตือนขยายอยู่)

ใน Android 10 (API ระดับ 29) ขึ้นไป คุณสามารถสมัครรับการเรียกกลับ onTopResumedActivityChanged() เพื่อรับการแจ้งเตือนเมื่อกิจกรรมได้รับหรือเสียตำแหน่งที่กลับมาทำงานอีกครั้งสูงสุด สถานะนี้เทียบเท่ากับสถานะ "กลับมาทำงานอีกครั้ง" ก่อน Android 10 และอาจเป็นประโยชน์เป็นคำแนะนำในกรณีที่แอปของคุณใช้ทรัพยากรแบบไม่แชร์หรือแบบสําคัญเพียงรายการเดียวซึ่งอาจต้องแชร์กับแอปอื่นๆ

ลักษณะการทํางานของแอตทริบิวต์ resizeableActivity ไฟล์ Manifest ก็มีการเปลี่ยนแปลงด้วย หากแอปตั้งค่า resizeableActivity=false ใน Android 10 (API ระดับ 29) ขึ้นไป ระบบอาจทำให้แอปอยู่ในโหมดความเข้ากันได้เมื่อขนาดหน้าจอที่ใช้ได้เปลี่ยนแปลงไป หรือเมื่อแอปย้ายจากหน้าจอหนึ่งไปยังอีกหน้าจอหนึ่ง

แอปสามารถใช้แอตทริบิวต์ android:minAspectRatio ที่เปิดตัวใน Android 10 เพื่อระบุสัดส่วนหน้าจอที่แอปรองรับ

ตั้งแต่เวอร์ชัน 3.5 เป็นต้นไป เครื่องมือจำลองของ Android Studio จะมีอุปกรณ์เสมือนขนาด 7.3 นิ้วและ 8 นิ้วสำหรับทดสอบโค้ดด้วยหน้าจอขนาดใหญ่

ดูข้อมูลเพิ่มเติมได้ที่ออกแบบแอปสำหรับอุปกรณ์แบบพับได้