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 Runtime ยอมรับเฉพาะไฟล์ OAT ที่ระบบสร้างขึ้นเท่านั้น
Android Runtime (ART) จะไม่เรียกใช้ dex2oat จากกระบวนการของแอปพลิเคชันอีกต่อไป การเปลี่ยนแปลงนี้หมายความว่า ART จะยอมรับเฉพาะไฟล์ OAT ที่ระบบสร้างขึ้นเท่านั้น
การบังคับใช้ความถูกต้องของ AOT ใน ART
ในอดีต การคอมไพล์แบบ Ahead-Of-Time (AOT) ที่ดำเนินการโดย Android Runtime (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) ขึ้นไป คุณสามารถสมัครรับข้อมูล Callback onTopResumedActivityChanged() เพื่อรับการแจ้งเตือนเมื่อกิจกรรมได้รับหรือสูญเสียตำแหน่งที่กลับมาทำงานอีกครั้งที่อยู่ด้านบนสุด ซึ่งเทียบเท่ากับสถานะกลับมาทำงานอีกครั้งก่อน Android 10 และอาจมีประโยชน์เป็นคำแนะนำหากแอปของคุณใช้ทรัพยากรแบบเอกสิทธิ์เฉพาะหรือแบบซิงเกิลตันที่อาจต้องแชร์กับแอปอื่นๆ
ลักษณะการทำงานของแอตทริบิวต์ไฟล์ Manifest resizeableActivity ก็มีการเปลี่ยนแปลงเช่นกัน หากแอปตั้งค่า resizeableActivity=false ใน Android 10 (ระดับ API 29) ขึ้นไป ระบบอาจกำหนดให้แอปอยู่ในโหมดความเข้ากันได้เมื่อขนาดหน้าจอที่ใช้ได้มีการเปลี่ยนแปลง หรือหากแอปย้ายจากหน้าจอหนึ่งไปยังอีกหน้าจอหนึ่ง
แอปสามารถใช้แอตทริบิวต์ android:minAspectRatio ที่เปิดตัวใน Android 10 เพื่อระบุอัตราส่วนหน้าจอที่แอปรองรับ
ตั้งแต่เวอร์ชัน 3.5 เป็นต้นไป เครื่องมือโปรแกรมจำลองของ Android Studio จะมีอุปกรณ์เสมือนจริงขนาด 7.3 นิ้วและ 8 นิ้วสำหรับการทดสอบโค้ดกับหน้าจอขนาดใหญ่ขึ้น
ดูข้อมูลเพิ่มเติมได้ที่ออกแบบแอปสำหรับอุปกรณ์แบบพับได้