พร้อมกับฟีเจอร์และความสามารถใหม่ๆ แล้ว Android 8.0 (API ระดับ 26) มีการเปลี่ยนแปลงการทำงานของระบบและ API อย่างหลากหลาย เอกสารนี้ เน้นไปที่การเปลี่ยนแปลงสำคัญๆ ที่คุณควรทำความเข้าใจและนำมาปรับใช้ ในแอปของคุณ
การเปลี่ยนแปลงเหล่านี้ส่วนใหญ่จะมีผลกับแอปทั้งหมด ไม่ว่าจะเป็นเวอร์ชันใดก็ตาม Android ที่ผู้ใช้กำหนดเป้าหมาย อย่างไรก็ตาม การเปลี่ยนแปลงหลายรายการจะส่งผลต่อการกำหนดเป้าหมายแอปเท่านั้น Android 8.0 เพื่อเพิ่มความชัดเจน จะแบ่งออกเป็น 2 ส่วน ได้แก่ การเปลี่ยนแปลงสำหรับทุกแอป และการเปลี่ยนแปลงสำหรับการกำหนดเป้าหมายแอป Android 8.0
การเปลี่ยนแปลงสำหรับแอปทั้งหมด
การเปลี่ยนแปลงลักษณะการทำงานเหล่านี้จะมีผลกับ
ขีดจำกัดการดำเนินการในเบื้องหลัง
เป็นหนึ่งในการเปลี่ยนแปลงที่ Android 8.0 (API ระดับ 26) เพิ่มเข้ามา ยืดอายุการใช้งานแบตเตอรี่ เมื่อแอปของคุณเข้าสู่ แคชไว้ สถานะที่ไม่มีการเคลื่อนไหว คอมโพเนนต์ ระบบจะปลดล็อกการทำงานขณะล็อกที่แอปค้างไว้
นอกจากนี้ เพื่อปรับปรุงประสิทธิภาพของอุปกรณ์ ระบบจะจำกัดบางอย่าง ลักษณะการทำงานของแอปที่ไม่ได้ทำงานอยู่ในเบื้องหน้า ดังนี้
- ตอนนี้แอปที่ทํางานอยู่เบื้องหลังจะมีข้อจํากัดด้านความอิสระ ผู้ใช้เข้าถึงบริการในเบื้องหลังได้
- แอปไม่สามารถใช้ไฟล์ Manifest เพื่อลงทะเบียนสำหรับการออกอากาศโดยนัยส่วนใหญ่ (ซึ่งก็คือการออกอากาศที่ไม่ได้กำหนดเป้าหมายที่แอปโดยเฉพาะ)
โดยค่าเริ่มต้น ข้อจำกัดเหล่านี้จะมีผลกับแอปที่กำหนดเป้าหมายเป็น O เท่านั้น อย่างไรก็ตาม ผู้ใช้สามารถเปิดใช้ข้อจำกัดเหล่านี้สำหรับแอปใดก็ได้จากหน้าจอการตั้งค่า แม้ว่าแอปจะไม่ได้กำหนดเป้าหมาย O ก็ตาม
Android 8.0 (API ระดับ 26) ยังมีการเปลี่ยนแปลงเมธอดบางอย่างดังต่อไปนี้ด้วย
- ตอนนี้เมธอด
startService()
มีการส่งIllegalStateException
หากแอป ที่กำหนดเป้าหมายเป็น Android 8.0 จะพยายามใช้วิธีการนั้น ในสถานการณ์ที่ไม่ได้รับอนุญาตให้สร้างบริการที่ทำงานอยู่เบื้องหลัง - เมธอด
Context.startForegroundService()
ใหม่จะเริ่ม บริการที่ทำงานอยู่เบื้องหน้า ระบบอนุญาตให้แอป เพื่อโทรหาContext.startForegroundService()
แม้ว่าแอปจะเริ่มต้น ในเบื้องหลัง แต่แอปต้องเรียกใช้เมธอดstartForeground()
ของบริการนั้นภายในห้า วินาทีหลังจากสร้างบริการ
สำหรับข้อมูลเพิ่มเติม โปรดดู ขีดจำกัดของการดำเนินการในเบื้องหลัง
ขีดจำกัดตำแหน่งในเบื้องหลังของ Android
เพื่อรักษาแบตเตอรี่ ประสบการณ์ของผู้ใช้ และประสิทธิภาพของระบบ แอปที่ทำงานอยู่เบื้องหลังจะได้รับการอัปเดตตำแหน่งน้อยลงเมื่อใช้ในอุปกรณ์ ที่ใช้ Android 8.0 การเปลี่ยนแปลงลักษณะการทำงานนี้ส่งผลต่อแอปทั้งหมด ที่ได้รับการอัปเดตตำแหน่ง รวมถึงบริการ Google Play
การเปลี่ยนแปลงเหล่านี้จะมีผลกับ API ต่อไปนี้
- ผู้ให้บริการ Fused Location (FLP)
- การกำหนดเขตพื้นที่เสมือน
- การวัดของ GNSS
- ผู้จัดการสถานที่
- ตัวจัดการ Wi-Fi
โปรดทำตามขั้นตอนต่อไปนี้เพื่อตรวจสอบว่าแอปทำงานตามที่คาดไว้
- ตรวจสอบตรรกะของแอปและดูว่าคุณกำลังใช้ตำแหน่งล่าสุด API
- ทดสอบว่าแอปแสดงลักษณะการทำงานตามที่คุณคาดหวังสำหรับการใช้งานแต่ละครั้ง
- ลองใช้ รวม ผู้ให้บริการตำแหน่ง (FLP) หรือการกำหนดเขตพื้นที่เสมือนเพื่อจัดการกรณีการใช้งานที่ขึ้นอยู่กับ ตำแหน่งปัจจุบันของผู้ใช้
อ่านข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงเหล่านี้ได้ที่ ตำแหน่งในเบื้องหลัง ขีดจำกัด
แป้นพิมพ์ลัดของแอป
Android 8.0 (API ระดับ 26) มีการเปลี่ยนแปลงต่อไปนี้กับทางลัดของแอป
- หมายเลข
com.android.launcher.action.INSTALL_SHORTCUT
ที่ออกอากาศ มีผลกับแอปของคุณอีกต่อไป เนื่องจากตอนนี้แอปเป็นแบบส่วนตัว โดยปริยาย ออกอากาศ แต่คุณควรสร้างทางลัดของแอปโดยใช้requestPinShortcut()
จากคลาสShortcutManager
ACTION_CREATE_SHORTCUT
ตอนนี้ Intent สามารถสร้างทางลัดของแอปที่คุณจัดการโดยใช้ ชั้นเรียนShortcutManager
Intent นี้ยังสามารถสร้าง แป้นพิมพ์ลัดตัวเรียกใช้งานแบบเดิมที่ไม่ได้ทำงานด้วยShortcutManager
ก่อนหน้านี้ Intent นี้อาจ สร้างเฉพาะแป้นพิมพ์ลัด Launcher เดิม- แป้นพิมพ์ลัดที่สร้างขึ้นโดยใช้
requestPinShortcut()
และทางลัดที่สร้างในกิจกรรมที่จัดการ วันที่ACTION_CREATE_SHORTCUT
ตอนนี้ Intent ได้กลายเป็นทางลัดของแอปโดยสมบูรณ์แล้ว ด้วยเหตุนี้ แอปจะอัปเดตแอปเหล่านั้น โดยใช้เมธอดในShortcutManager
- แป้นพิมพ์ลัดเดิมยังคงฟังก์ชันจากเวอร์ชันก่อนหน้าของ Android แต่คุณต้องแปลงเป็นทางลัดของแอปด้วยตนเองในแอป
ดูข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงทางลัดของแอปได้ที่ การปักหมุดทางลัดและ คำแนะนำเกี่ยวกับวิดเจ็ต
ภาษาและการปรับให้เป็นสากล
Android 7.0 (API ระดับ 24) นำเสนอแนวคิดที่ว่า
ระบุภาษาของหมวดหมู่เริ่มต้น แต่ API บางรายการยังคงใช้
Locale.getDefault()
ทั่วไป
โดยไม่มีอาร์กิวเมนต์ เมื่อควรใช้ตำแหน่งที่ตั้งของหมวดหมู่ DISPLAY
ที่เป็นค่าเริ่มต้นแทน ใน Android 8.0 (API ระดับ 26)
เมธอดต่อไปนี้ใช้ Locale.getDefault(Category.DISPLAY)
แทน Locale.getDefault()
:
Locale.getDisplayScript(Locale)
และ
จะกลับไปเป็น Locale.getDefault()
เมื่อ
ระบุค่า displayScript สำหรับ Locale
แล้ว
ไม่สามารถใช้อาร์กิวเมนต์
การเปลี่ยนแปลงอื่นๆ ที่เกี่ยวข้องกับภาษาและการปรับให้เป็นสากล ดังต่อไปนี้:
- การเรียกใช้
Currency.getDisplayName(null)
จะโยนNullPointerException
ตรงกับลักษณะการทำงานที่บันทึกไว้ - การแยกวิเคราะห์ชื่อเขตเวลามีการเปลี่ยนแปลง ก่อนหน้านี้
อุปกรณ์ Android ใช้ค่านาฬิกาของระบบซึ่งสุ่มตัวอย่างเมื่อบูต
เวลาในการแคชชื่อเขตเวลาที่ใช้สําหรับวันที่แยกวิเคราะห์
ครั้ง ดังนั้นการแยกวิเคราะห์อาจได้รับผลกระทบในเชิงลบ หากระบบ
นาฬิกาไม่ถูกต้องขณะเปิดเครื่อง หรือในบางกรณีซึ่งเกิดขึ้นไม่บ่อยนัก
ในกรณีทั่วไป ตรรกะการแยกวิเคราะห์จะใช้ ICU และ ค่านาฬิกาของระบบปัจจุบันเมื่อแยกวิเคราะห์ชื่อเขตเวลา ช่วงเวลานี้ การเปลี่ยนแปลงจะให้ผลลัพธ์ที่ถูกต้องมากกว่า ซึ่งอาจแตกต่างกับก่อนหน้านี้ เวอร์ชัน Android เมื่อแอปของคุณใช้ชั้นเรียน เช่น
SimpleDateFormat
- Android 8.0 (API ระดับ 26) จะอัปเดตเวอร์ชันของ ICU เป็นเวอร์ชัน 58
กรอบเวลาการแจ้งเตือน
หากแอปใช้ SYSTEM_ALERT_WINDOW
และใช้หน้าต่างประเภทใดประเภทหนึ่งต่อไปนี้เพื่อพยายามแสดง
หน้าต่างการแจ้งเตือนเหนือแอปและหน้าต่างระบบอื่นๆ
...หน้าต่างเหล่านี้จะปรากฏใต้หน้าต่างที่ใช้
หน้าต่าง TYPE_APPLICATION_OVERLAY
ประเภท หากแอปกำหนดเป้าหมายเป็น Android 8.0 (API ระดับ 26) แอปนั้นจะใช้
TYPE_APPLICATION_OVERLAY
ประเภทหน้าต่างที่จะแสดงหน้าต่างการแจ้งเตือน
สำหรับข้อมูลเพิ่มเติม โปรดดูที่ประเภทหน้าต่างทั่วไปสำหรับ ส่วนภายในการเปลี่ยนแปลงลักษณะการทำงานสำหรับApps ซึ่งกำหนดเป้าหมายเป็น Android 8.0
การป้อนข้อมูลและการนำทาง
เมื่อแอป Android ถือกำเนิดขึ้นบน ChromeOS และรูปแบบของอุปกรณ์ขนาดใหญ่อื่นๆ เช่น แท็บเล็ต เราพบว่าการเพิ่มขึ้นของการใช้งานการนำทางด้วยแป้นพิมพ์ภายใน แอป Android ใน Android 8.0 (API ระดับ 26) เราได้ดำเนินการแก้ไขอีกครั้งโดยใช้ แป้นพิมพ์เป็นอุปกรณ์อินพุตการนำทาง ทำให้มีความเสถียรมากขึ้น รูปแบบที่คาดการณ์ได้สำหรับการนำทางโดยใช้ลูกศรและแท็บ
โดยเฉพาะอย่างยิ่ง เราได้ทำการเปลี่ยนแปลงต่อไปนี้ในการโฟกัสองค์ประกอบ พฤติกรรม:
-
ถ้าคุณยังไม่ได้กำหนดสีสถานะโฟกัสสำหรับ ออบเจ็กต์
View
รายการ (ทั้งเบื้องหน้าหรือเบื้องหลัง ถอนออกได้) ปัจจุบันเฟรมเวิร์กจะกำหนดสีไฮไลต์เริ่มต้นให้กับแท็กView
ไฮไลต์ที่โฟกัสนี้ เป็นระลอกคลื่นที่ถอนออก โดยอิงตามธีมของกิจกรรมหากไม่ต้องการให้ออบเจ็กต์
View
ใช้ค่าเริ่มต้นนี้ ไฮไลต์เมื่อได้รับโฟกัส ให้ตั้งandroid:defaultFocusHighlightEnabled
แอตทริบิวต์ให้กับfalse
ในไฟล์ XML ของเลย์เอาต์ที่มีส่วนView
หรือเดินทางในfalse
ไปยังsetDefaultFocusHighlightEnabled()
ในตรรกะ UI ของแอป - ในการทดสอบว่าการป้อนข้อมูลผ่านแป้นพิมพ์มีผลต่อการโฟกัสองค์ประกอบ UI อย่างไร คุณสามารถเปิด ภาพวาด > แสดงตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ขอบเขตเลย์เอาต์ ใน Android 8.0 ตัวเลือกนี้จะแสดงเครื่องหมาย "X" เหนือองค์ประกอบที่มี โฟกัส
นอกจากนี้ องค์ประกอบแถบเครื่องมือทั้งหมดใน Android 8.0 จะ คลัสเตอร์การนำทางด้วยแป้นพิมพ์ ทำให้ผู้ใช้สามารถเข้าและออกจากแถบเครื่องมือ ทั้งหมด
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีปรับปรุงการรองรับการไปยังส่วนต่างๆ ด้วยแป้นพิมพ์ภายใน โปรดอ่านหัวข้อการสนับสนุน คำแนะนำการไปยังส่วนต่างๆ ด้วยแป้นพิมพ์
กรอกข้อมูลเว็บฟอร์มอัตโนมัติ
ตอนนี้เมื่อปุ่มป้อนข้อความอัตโนมัติ
เฟรมเวิร์กรองรับฟังก์ชันป้อนข้อความอัตโนมัติในตัว
เมธอดต่อไปนี้ที่เกี่ยวข้องกับออบเจ็กต์ WebView
มีการเปลี่ยนแปลง
สำหรับแอปที่ติดตั้งในอุปกรณ์ที่ใช้ Android 8.0 (API ระดับ 26) ให้ทำดังนี้
WebSettings
-
-
getSaveFormData()
ตอนนี้เมธอดจะแสดงfalse
ก่อนหน้านี้ เมธอดนี้แสดงผลtrue
แทน - การโทร
ปฏิเสธ
setSaveFormData()
ราย จะส่งผลใดๆ ต่อคุณอีกต่อไป
-
WebViewDatabase
-
- การโทร
ปฏิเสธ
clearFormData()
ราย จะส่งผลใดๆ ต่อคุณอีกต่อไป -
hasFormData()
วิธี จะแสดงfalse
ก่อนหน้านี้ เมธอดนี้แสดงผลtrue
เมื่อแบบฟอร์มมีข้อมูล
- การโทร
ปฏิเสธ
การช่วยเหลือพิเศษ
Android 8.0 (API ระดับ 26) มีการเปลี่ยนแปลงการช่วยเหลือพิเศษต่อไปนี้
-
เฟรมเวิร์กการช่วยเหลือพิเศษจะแปลงท่าทางสัมผัสการแตะสองครั้งทั้งหมดเป็น
ACTION_CLICK
การดำเนินการ การเปลี่ยนแปลงนี้ช่วยให้ TalkBack ทำงานคล้ายกับอื่นๆ มากขึ้น บริการการช่วยเหลือพิเศษหากออบเจ็กต์
View
ของแอปใช้การแตะที่กำหนดเอง คุณควรตรวจสอบว่าอุปกรณ์ยังคงทำงานกับ TalkBack ได้อยู่ คุณอาจ เพียงแค่ลงทะเบียนเครื่องจัดการคลิกที่View
ต่างๆ หาก TalkBack ยังคงไม่รู้จักท่าทางสัมผัสที่ทำในรายการเหล่านี้ ออบเจ็กต์View
รายการ ลบล้างperformAccessibilityAction()
- ตอนนี้บริการช่วยเหลือพิเศษรับรู้ถึง
ClickableSpan
อินสแตนซ์ภายในแอปของคุณTextView
ออบเจ็กต์
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีทําให้แอปเข้าถึงได้ง่ายขึ้นที่ การช่วยเหลือพิเศษ
เครือข่ายและการเชื่อมต่อ HTTP(S)
Android 8.0 (API ระดับ 26) มีการเปลี่ยนแปลงลักษณะการทำงานดังต่อไปนี้ เครือข่ายและการเชื่อมต่อ HTTP(S):
- คำขอ OPTIONS ที่ไม่มีเนื้อหามี
Content-Length: 0
ส่วนหัว ก่อนหน้านี้ไม่มีส่วนหัวContent-Length
- HttpURLConnection จะปรับ URL ที่มีเส้นทางว่างให้เป็นปกติด้วยการต่อท้ายด้วย
เครื่องหมายขีดทับหลังชื่อโฮสต์หรือผู้ออกใบรับรองพร้อมด้วยเครื่องหมายทับ ตัวอย่างเช่น
แปลง
http://example.com
เป็นhttp://example.com/
- ตัวเลือกพร็อกซีแบบกำหนดเองที่ตั้งค่าผ่าน ProxySelector.setDefault() กำหนดเป้าหมายเฉพาะที่อยู่ (รูปแบบ โฮสต์ และพอร์ต) ของ URL ที่ขอ ดังนั้น การเลือกพร็อกซีอาจอิงตามค่าเหล่านั้นเท่านั้น URL ที่ส่งไปยังตัวเลือกพร็อกซีที่กำหนดเอง จะไม่รวม URL ที่ส่งคำขอ เส้นทาง พารามิเตอร์การค้นหา หรือส่วนย่อย
- URI ต้องไม่มีป้ายกำกับที่ว่างเปล่า
ก่อนหน้านี้ แพลตฟอร์มนี้รองรับวิธีหลีกเลี่ยงปัญหาเพื่อยอมรับป้ายกำกับที่ว่างเปล่าใน ชื่อโฮสต์ ซึ่งเป็นการใช้ URI อย่างผิดกฎหมาย วิธีแก้ปัญหานี้ใช้สำหรับ ความเข้ากันได้กับรุ่นของ libcore รุ่นเก่า นักพัฒนาซอฟต์แวร์ที่ใช้ API จะเห็นข้อความ ADB อย่างไม่ถูกต้อง: "URI example..com มีป้ายกำกับว่างเปล่าใน ชื่อโฮสต์ ข้อความนี้มีรูปแบบไม่ถูกต้องและจะไม่ได้รับการยอมรับใน Android ในอนาคต รุ่นต่างๆ" Android 8.0 จะนำวิธีแก้ปัญหาชั่วคราวนี้ออก ระบบจะส่งคืน null สำหรับ URI ที่มีรูปแบบไม่ถูกต้อง
- การใช้งาน HttpsURLConnection ของ Android 8.0 ไม่ทำงานสำรองเวอร์ชันโปรโตคอล TLS/SSL ที่ไม่ปลอดภัย
- มีการเปลี่ยนแปลงการจัดการการเชื่อมต่อ HTTP(S) ของ Tunnel ดังนี้
- เมื่อทำอุโมงค์การเชื่อมต่อ HTTPS ผ่านการเชื่อมต่อ ระบบจะ วางหมายเลขพอร์ต (:443) ในบรรทัดโฮสต์อย่างถูกต้องเมื่อส่ง ข้อมูลไปยังเซิร์ฟเวอร์ตัวกลาง ก่อนหน้านี้ พอร์ต ตัวเลขที่เกิดขึ้นในบรรทัด CONNECT เท่านั้น
- ระบบจะไม่ส่ง User Agent และการให้สิทธิ์พร็อกซีอีกต่อไป
จากคำขอที่ส่งผ่านอุโมงค์ข้อมูลไปยังพร็อกซีเซิร์ฟเวอร์
ระบบจะไม่ส่งส่วนหัวการให้สิทธิ์พร็อกซีใน HttpURL เชื่อมต่อไปยังพร็อกซีเมื่อตั้งค่าพารามิเตอร์ อุโมงค์ข้อมูล แต่ระบบจะสร้างส่วนหัวการให้สิทธิ์พร็อกซีแทน และส่งไปยังพร็อกซีเมื่อพร็อกซีนั้นส่ง HTTP 407 เพื่อตอบสนองคำขอเริ่มต้น
ในทำนองเดียวกัน ระบบจะไม่คัดลอกส่วนหัวของ User Agent อีกต่อไป จากคำขอที่ส่งผ่านไปยังคำขอพร็อกซีที่ตั้งค่า อุโมงค์ข้อมูล แต่ไลบรารีจะสร้างส่วนหัว user-agent แทน อีกครั้ง
send(java.net.DatagramPacket)
จะมี SocketException หากก่อนหน้านี้ดำเนินการ Connect() ไม่สำเร็จ- DatagramSocket.connect() ตั้งค่า pendingSocketException หากมี ข้อผิดพลาดภายใน ก่อนหน้า Android 8.0 คือ Rev() ที่ตามมาภายหลัง เรียกใช้ SocketException แม้ว่าการเรียกใช้ send() จะสำเร็จก็ตาม เพื่อความสอดคล้อง ตอนนี้การโทรทั้งสองจะมี SocketException
- InetAddress.isReachable() พยายามใช้ ICMP ก่อนเปลี่ยนกลับไปใช้เสียงสะท้อนของ TCP
- โฮสต์บางรายการที่บล็อกพอร์ต 7 (TCP Echo) เช่น google.com อาจ ให้เข้าถึงได้ หากพาร์ทเนอร์ยอมรับโปรโตคอล Echo แบบ ICMP
- สำหรับโฮสต์ที่เข้าถึงไม่ได้จริงๆ การเปลี่ยนแปลงนี้หมายความว่าจำนวนที่เพิ่มขึ้นถึง 2 เท่า ใช้เวลามากกว่า ก่อนที่การเรียกจะกลับมา
บลูทูธ
Android 8.0 (API ระดับ 26) ได้ทำการเปลี่ยนแปลงต่อไปนี้กับความยาวของ
ข้อมูลที่ ScanRecord.getBytes()
จะเรียกเมธอด:
- เมธอด
getBytes()
ไม่มีสมมติฐานเกี่ยวกับ จำนวนไบต์ที่ได้รับ ดังนั้น แอปจึงไม่ควรพึ่งพา จำนวนไบต์ต่ำสุดหรือสูงสุดที่แสดงผลได้ แต่ควรประเมิน ความยาวของอาร์เรย์ผลลัพธ์ - อุปกรณ์ที่เข้ากันได้กับบลูทูธ 5 อาจส่งข้อมูลเกินความยาว ขนาดสูงสุดประมาณ 60 ไบต์ก่อนหน้า
- หากอุปกรณ์ระยะไกลไม่ตอบสนองต่อการสแกน น้อยกว่า 60 ไบต์ ได้เช่นกัน
การเชื่อมต่อที่ราบรื่น
Android 8.0 (API ระดับ 26) ทำการปรับปรุงหลายอย่างให้กับการตั้งค่า Wi-Fi เพื่อให้เลือกได้ง่ายขึ้น เครือข่าย Wi-Fi ที่มอบประสบการณ์ที่ดีที่สุดแก่ผู้ใช้ การเปลี่ยนแปลงที่เฉพาะเจาะจงมีดังนี้
- ปรับปรุงความเสถียรและความน่าเชื่อถือ
- UI ที่อ่านง่ายขึ้น
- เมนูค่ากำหนด Wi-Fi ที่รวมเป็นหนึ่งเดียว
- ในอุปกรณ์ที่เข้ากันได้ จะเปิดใช้งาน Wi-Fi โดยอัตโนมัติเมื่อเครือข่ายที่บันทึกไว้คุณภาพสูง อยู่ใกล้
ความปลอดภัย
Android 8.0 มีเครื่องมือเกี่ยวกับความปลอดภัยต่อไปนี้ การเปลี่ยนแปลง:
- แพลตฟอร์มนี้ไม่สนับสนุน SSLv3 อีกต่อไป
- เมื่อสร้างการเชื่อมต่อ HTTPS กับเซิร์ฟเวอร์ที่ไม่ถูกต้อง
ใช้การเจรจาเวอร์ชันโปรโตคอล TLS
HttpsURLConnection
ไม่ลองใช้วิธีแก้ปัญหาเบื้องต้นแล้ว เปลี่ยนไปใช้โปรโตคอล TLS รุ่นก่อนหน้า แล้วลองใหม่ - Android 8.0 (API ระดับ 26) ใช้การประมวลผลที่ปลอดภัย (SECCOMP) กรองแอปทั้งหมด รายการการเรียก Syscall ที่อนุญาตจะจำกัดเฉพาะ ผ่านไบโอนิก แม้ว่าจะมี Syscall อื่นๆ ให้บริการ สำหรับความเข้ากันได้แบบย้อนหลัง เราขอแนะนำให้เทียบกับการใช้งาน
- ตอนนี้ออบเจ็กต์
WebView
ของแอปทำงานแบบหลายกระบวนการแล้ว เนื้อหาเว็บจะมีการจัดการในกระบวนการที่แยกต่างหากจาก ที่มีขั้นตอนของแอป เพื่อการรักษาความปลอดภัยที่ดียิ่งขึ้น -
คุณไม่สามารถคาดเดาเองว่า APK อยู่ในไดเรกทอรีที่ชื่อลงท้ายได้อีกต่อไป
ใน -1 หรือ -2 แอปควรใช้
sourceDir
เพื่อรับ และไม่ต้องอาศัยรูปแบบไดเรกทอรีโดยตรง - สำหรับข้อมูลเกี่ยวกับการเพิ่มประสิทธิภาพการรักษาความปลอดภัยที่เกี่ยวข้องกับการใช้โฆษณาเนทีฟ โปรดดูไลบรารีเนทีฟ
นอกจากนี้ Android 8.0 (API ระดับ 26) ยังมีการเปลี่ยนแปลงเกี่ยวกับการติดตั้งดังต่อไปนี้ด้วย แอปที่ไม่รู้จักจากแหล่งที่มาที่ไม่รู้จัก:
- ค่าของการตั้งค่าแบบเดิม
INSTALL_NON_MARKET_APPS
ในขณะนี้ 1 เสมอ เพื่อพิจารณาว่าแหล่งที่มาที่ไม่รู้จักสามารถติดตั้งแอปโดยใช้ โปรแกรมติดตั้งแพ็กเกจ คุณควรใช้ค่าผลลัพธ์canRequestPackageInstalls()
- หากคุณพยายามเปลี่ยนค่าของ
INSTALL_NON_MARKET_APPS
กำลังใช้setSecureSetting()
UnsupportedOperationException
ได้ เพื่อป้องกันไม่ให้ผู้ใช้ติดตั้งแอปที่ไม่รู้จักโดยใช้แอปที่ไม่รู้จัก คุณควรใช้ฟิลด์ ผู้ใช้DISALLOW_INSTALL_UNKNOWN_SOURCES
คน ข้อจำกัด -
โปรไฟล์ที่มีการจัดการที่สร้างในอุปกรณ์ที่ใช้ Android 8.0 (API ระดับ 26) จะมี
ผู้ใช้
DISALLOW_INSTALL_UNKNOWN_SOURCES
คน เปิดใช้การจำกัดแล้ว สําหรับโปรไฟล์ที่มีการจัดการซึ่งมีอยู่แล้วในอุปกรณ์ที่ มีการอัปเกรดเป็น Android 8.0 ผู้ใช้DISALLOW_INSTALL_UNKNOWN_SOURCES
คน การจำกัดจะเปิดใช้โดยอัตโนมัติเว้นแต่เจ้าของโปรไฟล์จะระบุอย่างชัดเจน ปิดการใช้งานข้อจำกัดนี้ (ก่อนการอัปเกรด) โดยการตั้งค่าINSTALL_NON_MARKET_APPS
ต่อ 1
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการติดตั้งแอปที่ไม่รู้จัก โปรดดูที่ แอปที่ไม่รู้จัก คำแนะนำในการติดตั้งสิทธิ์
สำหรับหลักเกณฑ์เพิ่มเติมเกี่ยวกับการทำให้แอปปลอดภัยยิ่งขึ้น โปรดดู ความปลอดภัยสำหรับนักพัฒนาแอป Android
ความเป็นส่วนตัว
Android 8.0 (API ระดับ 26) มีคุณสมบัติดังต่อไปนี้เกี่ยวกับความเป็นส่วนตัว เปลี่ยนแปลงในแพลตฟอร์ม
- ปัจจุบันแพลตฟอร์มจะจัดการกับตัวระบุในลักษณะที่ต่างออกไป
-
สำหรับแอปที่ติดตั้งก่อน OTA ในเวอร์ชัน
Android 8.0 (API ระดับ 26)
(API ระดับ 26) ค่าของ
ANDROID_ID
ยังคงเหมือนเดิม เว้นแต่จะถอนการติดตั้งแล้วติดตั้งใหม่หลังจาก OTA เพื่อเก็บรักษาค่า หลังจาก OTA แล้ว นักพัฒนาซอฟต์แวร์สามารถเชื่อมโยงค่าเก่าและค่าใหม่โดยใช้ การสำรองข้อมูลคีย์/ค่า - สำหรับแอปที่ติดตั้งในอุปกรณ์ที่ใช้ Android 8.0 ค่าของ
กำหนดขอบเขตระดับ
ANDROID_ID
แล้ว ต่อคีย์ App Signing และต่อผู้ใช้ ค่าของANDROID_ID
ไม่ซ้ำ สำหรับชุดคีย์การลงนามแอป ผู้ใช้ และอุปกรณ์แต่ละชุด ด้วยเหตุนี้ แอปที่มีคีย์การรับรองต่างกันจะทำงานบนอุปกรณ์เดียวกัน จะไม่เห็นรหัส Android รหัสเดียวกันอีก (แม้จะเป็นผู้ใช้รายเดียวกัน) - ค่าของ
ANDROID_ID
ไม่เปลี่ยนแปลงเมื่อถอนการติดตั้งหรือติดตั้งแพ็กเกจใหม่ หาก คีย์ Signing เหมือนกัน (และแอปไม่ได้ติดตั้งก่อนที่จะมีการ OTA ไปยัง Android 8.0) - ค่าของ
ANDROID_ID
ไม่เปลี่ยนแปลงแม้ว่าการอัปเดตระบบจะทำให้คีย์ Signing ของแพ็กเกจเปลี่ยนแปลงไปก็ตาม - ในอุปกรณ์ที่จัดส่งด้วยบริการ Google Play และรหัสโฆษณา
คุณต้องใช้
รหัสโฆษณา ระบบที่เป็นมาตรฐานและใช้งานง่ายในการสร้างรายได้จากแอป
รหัสโฆษณาคือรหัสที่ไม่ซ้ำกันและผู้ใช้สามารถรีเซ็ตได้สำหรับใช้กับโฆษณา มีให้แล้ว
ตามบริการ Google Play
ผู้ผลิตอุปกรณ์อื่นๆ ควรดำเนินการต่อ เพื่อระบุ
ANDROID_ID
-
สำหรับแอปที่ติดตั้งก่อน OTA ในเวอร์ชัน
Android 8.0 (API ระดับ 26)
(API ระดับ 26) ค่าของ
- การค้นหาพร็อพเพอร์ตี้ของระบบ
net.hostname
จะทำให้เกิดค่า Null ผลลัพธ์
การบันทึกข้อยกเว้นที่ตรวจไม่พบ
หากแอปติดตั้ง Thread.UncaughtExceptionHandler
ที่ติดตั้ง
ไม่เรียกผ่านไปยัง Thread.UncaughtExceptionHandler
เริ่มต้น
ระบบจะทำ
ไม่หยุดการทำงานของแอปเมื่อมีข้อยกเว้นที่ตรวจไม่พบ เริ่มจาก
Android 8.0 (API ระดับ 26) ระบบจะบันทึกสแต็กเทรซข้อยกเว้นใน
ใหม่ ในแพลตฟอร์มเวอร์ชันก่อนหน้า ระบบจะไม่
ได้บันทึกสแต็กเทรซข้อยกเว้นแล้ว
เราขอแนะนำให้กำหนด Thread.UncaughtExceptionHandler
ที่กำหนดเอง
จะเรียกผ่านไปยัง
เครื่องจัดการเริ่มต้น แอปที่ทำตามคำแนะนำนี้จะไม่ได้รับผลกระทบ
การเปลี่ยนแปลงใน Android 8.0
การเปลี่ยนลายเซ็น findViewById()
ตอนนี้อินสแตนซ์ทั้งหมดของเมธอด findViewById()
จะแสดงผล
<T extends View> T
แทน View
การเปลี่ยนแปลงนี้
จะมีผลต่อไปนี้
- ซึ่งอาจทำให้โค้ดที่มีอยู่ตอนนี้มีประเภทผลลัพธ์ไม่ชัดเจน
เช่น ถ้ามีทั้ง
someMethod(View)
และsomeMethod(TextView)
ที่จะนำผลลัพธ์ของการเรียกไปยังfindViewById()
- เมื่อใช้ภาษาต้นฉบับ Java 8 การดำเนินการนี้ต้องมีการแคสต์อย่างชัดเจนไปยัง
View
เมื่อประเภทการแสดงผลเป็นแบบไม่จำกัด (เช่นassertNotNull(findViewById(...)).someViewMethod())
- การลบล้างของเมธอด
findViewById()
ที่ไม่ใช่ขั้นสุดท้าย (สำหรับ เช่นActivity.findViewById()
) อัปเดตประเภทแล้ว
การเปลี่ยนแปลงสถิติการใช้งานของผู้ให้บริการรายชื่อติดต่อ
ใน Android เวอร์ชันก่อนหน้า คอมโพเนนต์ผู้ให้บริการรายชื่อติดต่อ
ช่วยให้นักพัฒนาซอฟต์แวร์ได้รับข้อมูลการใช้งานของรายชื่อติดต่อแต่ละรายการ ข้อมูลการใช้งานนี้
จะแสดงข้อมูลของที่อยู่อีเมลแต่ละรายการ และหมายเลขโทรศัพท์แต่ละหมายเลขที่เชื่อมโยง
กับผู้ติดต่อ รวมทั้งจำนวนครั้งที่มีการติดต่อผู้ติดต่อนั้น
และเวลาล่าสุดที่มีการติดต่อ แอปที่ขอฟังก์ชัน
READ_CONTACTS
สิทธิ์นี้สามารถอ่านข้อมูลนี้ได้
แอปจะยังอ่านข้อมูลนี้ได้หากมีการขอ
READ_CONTACTS
สิทธิ์ ใน Android 8.0 (API ระดับ 26) ขึ้นไป คำค้นหาสำหรับข้อมูลการใช้งานจะแสดงผล
ค่าประมาณแทนค่าที่แน่นอน ระบบ Android จะดูแลรักษา
ด้วยตนเอง ดังนั้นการเปลี่ยนแปลงนี้ จึงจะไม่ส่งผลกระทบต่อ
เติมข้อความอัตโนมัติด้วย API
การเปลี่ยนแปลงลักษณะการทำงานนี้ส่งผลต่อพารามิเตอร์การค้นหาต่อไปนี้
การจัดการคอลเล็กชัน
AbstractCollection.removeAll()
และ AbstractCollection.retainAll()
ตอนนี้ก็จะส่ง NullPointerException
ทุกครั้ง ก่อนหน้านี้
ไม่ได้ใส่ NullPointerException
เมื่อคอลเล็กชันถูก
ว่างเปล่า การเปลี่ยนแปลงนี้จะทำให้ลักษณะการทำงานสอดคล้องกับเอกสาร
Android Enterprise
Android 8.0 (API ระดับ 26) มีการเปลี่ยนแปลง ลักษณะการทํางานของ API บางรายการและฟีเจอร์สําหรับแอปองค์กร ซึ่งรวมถึงอุปกรณ์ เครื่องมือควบคุมนโยบาย (DPC) การเปลี่ยนแปลงมีดังนี้
- ลักษณะการทํางานแบบใหม่ที่จะช่วยให้แอปรองรับโปรไฟล์งานในอุปกรณ์ที่มีการจัดการครบวงจร
- การเปลี่ยนแปลงการจัดการการอัปเดตระบบ การยืนยันแอป และการตรวจสอบสิทธิ์ของ เพื่อเพิ่มความสมบูรณ์ของอุปกรณ์และระบบ
- การปรับปรุงประสบการณ์ของผู้ใช้สำหรับการจัดสรร การแจ้งเตือน หน้าจอล่าสุดและ VPN ที่เปิดอยู่เสมอ
หากต้องการดูการเปลี่ยนแปลงทั้งหมดระดับองค์กรใน Android 8.0 (API ระดับ 26) และดูวิธีที่การเปลี่ยนแปลงจะเกิดขึ้น ส่งผลต่อแอปของคุณ โปรดอ่าน Android ในองค์กร
แอปที่กำหนดเป้าหมายเป็น Android 8.0
การเปลี่ยนแปลงลักษณะการทำงานเหล่านี้มีผลเฉพาะกับแอปที่กำหนดเป้าหมาย
Android 8.0 (API ระดับ 26) ขึ้นไป แอปที่คอมไพล์กับ Android 8.0
หรือตั้งค่า targetSdkVersion
เป็น Android 8.0 ขึ้นไปต้องแก้ไข
เพื่อรองรับลักษณะการทำงานเหล่านี้อย่างถูกต้อง หากเกี่ยวข้องกับแอป
กรอบเวลาการแจ้งเตือน
แอปที่ใช้ SYSTEM_ALERT_WINDOW
จะใช้หน้าต่างประเภทต่อไปนี้เพื่อแสดงหน้าต่างการแจ้งเตือนไม่ได้อีกต่อไป
เหนือแอปและหน้าต่างระบบอื่นๆ
แอปต้องใช้ประเภทหน้าต่างใหม่ที่เรียกว่า
TYPE_APPLICATION_OVERLAY
เมื่อใช้
หน้าต่าง TYPE_APPLICATION_OVERLAY
ประเภทเพื่อแสดงหน้าต่างการแจ้งเตือนสำหรับแอปของคุณ โปรดรักษาลักษณะเฉพาะต่อไปนี้
ของประเภทหน้าต่างใหม่
- หน้าต่างการแจ้งเตือนของแอปจะปรากฏใต้หน้าต่างระบบที่สำคัญเสมอ เช่น เป็นแถบสถานะและ IME
- ระบบจะย้ายหรือปรับขนาดหน้าต่างที่ใช้
TYPE_APPLICATION_OVERLAY
ประเภทหน้าต่างเพื่อปรับปรุงการนำเสนอหน้าจอ - เมื่อเปิดหน้าต่างแจ้งเตือน ผู้ใช้สามารถเข้าถึงการตั้งค่าเพื่อบล็อก
แอปไม่แสดงหน้าต่างการแจ้งเตือนที่แสดงโดยใช้
TYPE_APPLICATION_OVERLAY
ประเภทหน้าต่าง
การแจ้งเตือนการเปลี่ยนแปลงเนื้อหา
Android 8.0 (API ระดับ 26) เปลี่ยนลักษณะการทำงาน
ContentResolver.notifyChange()
และ registerContentObserver(Uri, boolean, ContentObserver)
ทำงานสำหรับแอปที่กำหนดเป้าหมายเป็น Android 8.0
ตอนนี้ API เหล่านี้กำหนดให้ต้องมี ContentProvider
ที่ถูกต้อง
คือหน่วยงานที่มีอำนาจในยูริสทั้งหมด การกำหนด ContentProvider
ที่ถูกต้องพร้อมด้วยสิทธิ์ที่เกี่ยวข้องจะ
ช่วยปกป้องแอปของคุณจากการเปลี่ยนแปลงเนื้อหาจากแอปที่เป็นอันตราย และป้องกันคุณ
ไม่ให้เปิดเผยข้อมูลส่วนตัวที่อาจรั่วไหลไปยังแอปที่เป็นอันตราย
ดูโฟกัส
วัตถุ View
ที่สามารถคลิกได้ขณะนี้ยังสามารถโฟกัสได้โดย
"ค่าเริ่มต้น" หากคุณต้องการให้ออบเจ็กต์ View
คลิกได้ แต่คลิกไม่ได้
ที่โฟกัสได้ ตั้งค่า
android:focusable
เป็น false
ในเลย์เอาต์
ไฟล์ XML ที่มี View
หรือส่งใน false
เป็น setFocusable()
ใน UI ของแอป
การจับคู่ User Agent ในการตรวจหาเบราว์เซอร์
Android 8.0 (API ระดับ 26) ขึ้นไปประกอบด้วย
สตริงตัวระบุบิลด์ OPR
อาจมีรูปแบบที่ตรงกัน
ทำให้ตรรกะการตรวจหาเบราว์เซอร์ระบุเบราว์เซอร์ที่ไม่ใช่ Opera ผิดพลาด
ตัวอย่างการจับคู่รูปแบบดังกล่าว ได้แก่
if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}
หากต้องการหลีกเลี่ยงปัญหาที่เกิดจากการระบุที่ไม่ถูกต้อง ให้ใช้สตริงอื่นที่ไม่ใช่
OPR
เป็นการจับคู่รูปแบบสำหรับเบราว์เซอร์ Opera
ความปลอดภัย
การเปลี่ยนแปลงต่อไปนี้ส่งผลต่อความปลอดภัยใน Android 8.0 (API ระดับ 26)
- หากการกำหนดค่าความปลอดภัยเครือข่ายของแอป
ตัวเลือก
มากขึ้นจากการรองรับการเข้าชมแบบข้อความธรรมดา (Cleartext)
ออบเจ็กต์
WebView
รายการเข้าถึงเว็บไซต์ผ่าน HTTP ไม่ได้ ชิ้น ออบเจ็กต์WebView
ต้องใช้ HTTPS แทน - มีการนำการตั้งค่าระบบอนุญาตแหล่งที่มาที่ไม่รู้จักออก ใน สิทธิ์ติดตั้งแอปที่ไม่รู้จักจะจัดการการติดตั้งแอปที่ไม่รู้จัก จากแหล่งที่มาที่ไม่รู้จัก ในการเรียนรู้เพิ่มเติมเกี่ยวกับสิทธิ์ใหม่นี้ โปรดดูที่ แอปที่ไม่รู้จัก คำแนะนำในการติดตั้งสิทธิ์
สำหรับหลักเกณฑ์เพิ่มเติมเกี่ยวกับการทำให้แอปปลอดภัยยิ่งขึ้น โปรดดู ความปลอดภัยสำหรับนักพัฒนาแอป Android
การเข้าถึงบัญชีและการค้นพบได้
ใน Android 8.0 (API ระดับ 26) แอปจะไม่สามารถเข้าถึงได้อีกต่อไป
ในบัญชีผู้ใช้ เว้นแต่ Authenticator จะเป็นเจ้าของบัญชีหรือ
ผู้ใช้ให้สิทธิ์การเข้าถึงนั้น
สิทธิ์GET_ACCOUNTS
จึงไม่เพียงพออีกต่อไป หากต้องการรับสิทธิ์เข้าถึงบัญชี แอปควร
ให้ใช้ AccountManager.newChooseAccountIntent()
หรือ Authenticator เฉพาะ
หลังจากเข้าถึงบัญชีแล้ว แอปจะโทร
AccountManager.getAccounts()
เพื่อเข้าถึงฟีดเหล่านั้น
การเลิกใช้งาน Android 8.0
LOGIN_ACCOUNTS_CHANGED_ACTION
แอป
ควรใช้แทน
addOnAccountsUpdatedListener()
เพื่อรับข้อมูลอัปเดตเกี่ยวกับบัญชีในระหว่างรันไทม์
สำหรับข้อมูลเกี่ยวกับ API ใหม่และวิธีการใหม่ๆ ที่เพิ่มเข้ามาสำหรับการเข้าถึงบัญชีและ การค้นพบได้ โปรดดูการเข้าถึงบัญชี และการค้นพบได้ในส่วน API ใหม่ของเอกสารนี้
ความเป็นส่วนตัว
การเปลี่ยนแปลงต่อไปนี้ส่งผลต่อความเป็นส่วนตัวใน Android 8.0 (API ระดับ 26)
-
พร็อพเพอร์ตี้ของระบบ
net.dns1
,net.dns2
เลิกให้บริการnet.dns3
และnet.dns4
แล้ว การเปลี่ยนแปลงที่ช่วยเพิ่มความเป็นส่วนตัวบนแพลตฟอร์ม -
หากต้องการรับข้อมูลเครือข่าย เช่น เซิร์ฟเวอร์ DNS แอปที่มี
ACCESS_NETWORK_STATE
สามารถลงทะเบียนNetworkRequest
หรือ ออบเจ็กต์NetworkCallback
รายการ ชั้นเรียนเหล่านี้มีให้บริการใน Android 5.0 (API ระดับ 21) ขึ้นไป -
เลิกใช้งาน Build.SERIAL แล้ว
แอปที่จำเป็นต้องทราบหมายเลขซีเรียลของฮาร์ดแวร์ควรดำเนินการแทน
ใช้เมธอด
Build.getSerial()
ใหม่ ซึ่ง ต้องมี วันที่READ_PHONE_STATE
สิทธิ์ -
LauncherApps
API ไม่อนุญาตให้ใช้โปรไฟล์งานอีกต่อไป เพื่อรับข้อมูลเกี่ยวกับโปรไฟล์หลัก เมื่อผู้ใช้กำลังอยู่ในที่ทำงาน ดังนั้น APILauncherApps
จะทํางานเสมือนว่าไม่มีแอป ติดตั้งอยู่ในโปรไฟล์อื่นๆ ภายในกลุ่มโปรไฟล์เดียวกัน เช่นเคย การพยายามเข้าถึงโปรไฟล์ที่ไม่เกี่ยวข้องจะทำให้เกิดการรักษาความปลอดภัย
สิทธิ์
เวอร์ชันก่อนหน้า Android 8.0 (API ระดับ 26) หากแอปขอสิทธิ์ ขณะรันไทม์ และได้รับสิทธิ์แล้ว ระบบยังสร้างข้อผิดพลาด ให้สิทธิ์ที่เหลือแก่แอปซึ่งเป็นของ กลุ่มสิทธิ์ ที่ได้ลงทะเบียนไว้ในไฟล์ Manifest
ลักษณะการทำงานนี้สำหรับแอปที่กำหนดเป้าหมายเป็น Android 8.0 ได้รับการแก้ไขแล้ว แอปจะได้รับสิทธิ์เฉพาะที่อย่างชัดเจน ที่ขอ แต่เมื่อผู้ใช้ให้สิทธิ์แอป คำขอสิทธิ์อื่นๆ ในกลุ่มสิทธิ์นั้น ให้สิทธิ์โดยอัตโนมัติ
ตัวอย่างเช่น สมมติว่าแอปมีทั้ง READ_EXTERNAL_STORAGE
และ
WRITE_EXTERNAL_STORAGE
ในไฟล์ Manifest
แอปขอ READ_EXTERNAL_STORAGE
และ
ที่ผู้ใช้ให้สิทธิ์ หากแอปกำหนดเป้าหมายเป็น API ระดับ 25 หรือต่ำกว่า ระบบจะยัง
ให้ WRITE_EXTERNAL_STORAGE
ในเวลาเดียวกัน
เนื่องจากอยู่ในกลุ่มสิทธิ์ STORAGE
เดียวกันและ
ซึ่งลงทะเบียนไว้ในไฟล์ Manifest หากแอปกำหนดเป้าหมายเป็น Android 8.0 (API ระดับ 26) ระบบจะให้สิทธิ์
เฉพาะ READ_EXTERNAL_STORAGE
ในเวลานั้น
แต่หากแอปขอ WRITE_EXTERNAL_STORAGE
ในภายหลัง ระบบจะดำเนินการทันที
ให้สิทธิ์ดังกล่าวโดยไม่ต้องแจ้งผู้ใช้
สื่อ
- เฟรมเวิร์กนี้สามารถ
การลดเสียงอัตโนมัติ
เพียงอย่างเดียว ในกรณีนี้ เมื่อแอปพลิเคชันอื่นขอโฟกัสด้วย
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
, แอปพลิเคชัน ที่มีโฟกัสลดลงแต่มักจะไม่ได้รับ วันที่onAudioFocusChange()
Callback และจะไม่ โฟกัสเสียงหายไป API ใหม่พร้อมที่จะลบล้างลักษณะการทำงานนี้สำหรับ แอปพลิเคชันที่ต้องหยุดชั่วคราวแทนที่จะหายไป - เมื่อผู้ใช้รับสาย สตรีมสื่อที่ใช้งานอยู่จะปิดเสียงตลอดระยะเวลาของ การโทร
- API เกี่ยวกับเสียงทั้งหมดควรใช้
AudioAttributes
แทนที่จะใช้ประเภทสตรีมเสียงเพื่ออธิบายกรณีการใช้งานการเล่นเสียง โปรดใช้ประเภทสตรีมเสียงต่อไปสำหรับการควบคุมระดับเสียงเท่านั้น การใช้งานสตรีมประเภทอื่นๆ ยังคงใช้งานได้ (เช่น อาร์กิวเมนต์streamType
ไปยังอาร์กิวเมนต์ที่เลิกใช้งานแล้ว เครื่องมือสร้างAudioTrack
) แต่ระบบจะบันทึกว่ามีข้อผิดพลาด - เมื่อใช้
AudioTrack
หากแอปพลิเคชัน ซึ่งต้องการบัฟเฟอร์เสียงที่ใหญ่พอ ของเฟรมเวิร์กจะพยายามใช้เอาต์พุตแบบ Deepบัฟเฟอร์ หากมี - ใน Android 8.0 (API ระดับ 26) การจัดการเหตุการณ์ปุ่มสื่อจะแตกต่างกันดังนี้
- การจัดการปุ่มสื่อ ในกิจกรรม UI ไม่เปลี่ยนแปลง: กิจกรรมเบื้องหน้ายังคงมีลำดับความสำคัญในการจัดการ เหตุการณ์ของปุ่มสื่อ
- หากกิจกรรมเบื้องหน้าไม่สามารถจัดการเหตุการณ์ของปุ่มสื่อ ระบบจะกำหนดเส้นทางเหตุการณ์ ไปยังแอปที่เล่นเสียงล่าสุดในเครื่อง สถานะที่ใช้งานอยู่ การแจ้งว่าไม่เหมาะสม และการเล่น สถานะของเซสชันสื่อจะไม่นำมาพิจารณาเมื่อกำหนดว่าแอปใดจะได้รับสื่อ เหตุการณ์ของปุ่ม
- หากมีการเผยแพร่เซสชันสื่อของแอปแล้ว
ระบบจะส่งเหตุการณ์ของปุ่มสื่อไปยัง
MediaButtonReceiver
หากมี - สำหรับกรณีอื่นๆ ระบบจะทิ้งเหตุการณ์ปุ่มสื่อ
ไลบรารีที่มาพร้อมเครื่อง
ในแอปที่กำหนดเป้าหมายเป็น Android 8.0 (API ระดับ 26) ไลบรารีแบบเนทีฟไม่ใช่ โหลดนานขึ้นหากมีเซกเมนต์โหลดที่ทั้งเขียนได้และ ไฟล์ปฏิบัติการ บางแอปอาจหยุดทำงานเนื่องจากการเปลี่ยนแปลงนี้ หากมีการอัปเดต ไลบรารีเนทีฟที่มีกลุ่มการโหลดที่ไม่ถูกต้อง นี่คือ มาตรการบังคับใช้การรักษาความปลอดภัย
สำหรับข้อมูลเพิ่มเติม โปรดดู กลุ่มที่เขียนได้และดำเนินการได้
การเปลี่ยนแปลง Linker จะเชื่อมโยงกับระดับ API ที่แอปกำหนดเป้าหมาย หากมี คือการเปลี่ยนแปลง Linker ที่ ระดับ API เป้าหมาย แอปไม่สามารถโหลดไลบรารี หากคุณกำลังกำหนดเป้าหมาย ระดับ API ที่ต่ำกว่าระดับ API ที่เกิดการเปลี่ยนแปลง Linker Logcat แสดงคำเตือน
การจัดการคอลเล็กชัน
ใน Android 8.0 (API ระดับ 26)
Collections.sort()
มีการใช้งานใน
ที่ด้านบนของ List.sort()
ย้อนกลับ
เป็นจริงใน Android 7.x (API ระดับ 24 และ 25):
การใช้งานเริ่มต้นของ List.sort()
ที่ชื่อ Collections.sort()
การเปลี่ยนแปลงนี้ช่วยให้ Collections.sort()
เพื่อใช้ประโยชน์จากList.sort()
ที่มีการเพิ่มประสิทธิภาพ
การนำไปใช้งานจริง แต่มีข้อจำกัดดังต่อไปนี้
การใช้งาน
List.sort()
ต้องไม่เรียกCollections.sort()
เนื่องจากจะทำให้สแต็กโอเวอร์โฟลว์ ด้วยการเกิดซ้ำอย่างไม่มีที่สิ้นสุด แต่หากต้องการการทำงานเริ่มต้น ในการใช้งานList
คุณควรหลีกเลี่ยงการลบล้างsort()
หากชั้นเรียนผู้ปกครองใช้
sort()
อย่างไม่เหมาะสม โดยปกติลบล้างList.sort()
ได้ ด้วยการติดตั้งใช้งานต่อยอดจากList.toArray()
,Arrays.sort()
และListIterator.set()
เช่น@Override public void sort(Comparator<? super E> c) { Object[] elements = toArray(); Arrays.sort(elements, c); ListIterator<E> iterator = (ListIterator<Object>) listIterator(); for (Object element : elements) { iterator.next(); iterator.set((E) element); } }
ในกรณีส่วนใหญ่ คุณยังสามารถลบล้าง
List.sort()
ด้วย การใช้งานที่มอบอำนาจให้ค่าเริ่มต้นอื่น การใช้งานโดยขึ้นอยู่กับระดับ API เช่น@Override public void sort(Comparator<? super E> comparator) { if (Build.VERSION.SDK_INT <= 25) { Collections.sort(this); } else { super.sort(comparator); } }
หากคุณทำในภายหลังเพียงเพราะต้องการมี
sort()
ที่ใช้ได้ใน API ทุกระดับ ลองตั้งชื่อที่ไม่ซ้ำ เช่นsortCompat()
แทนที่จะลบล้างsort()
-
ตอนนี้
Collections.sort()
นับเป็น การแก้ไขโครงสร้างใน แสดงรายการการติดตั้งใช้งานที่เรียกใช้sort()
ตัวอย่างเช่น ในเวอร์ชันของ แพลตฟอร์มก่อน Android 8.0 (API ระดับ 26) มีการทำซ้ำArrayList
และโทรหาsort()
ในนั้น ได้ผ่านการปรับปรุง จะส่งConcurrentModificationException
ถ้าจัดเรียงเสร็จแล้ว โดยโทรไปที่List.sort()
Collections.sort()
ไม่ได้ส่งข้อยกเว้นการเปลี่ยนแปลงนี้จะทำให้ลักษณะการทำงานของแพลตฟอร์มมีความสอดคล้องกันมากขึ้น ไม่ว่าจะเป็น ใหม่จะส่งผลให้เกิด
ConcurrentModificationException
ลักษณะการทำงานของการโหลดชั้นเรียน
Android 8.0 (API ระดับ 26) ตรวจสอบเพื่อให้มั่นใจว่าตัวโหลดคลาสไม่
ทำลายสมมติฐานของรันไทม์เมื่อโหลดคลาสใหม่ การตรวจสอบเหล่านี้
ดำเนินการไม่ว่าจะอ้างอิงคลาสจาก Java (จาก
forName()
)
Dalvik Bycode หรือ JNI แพลตฟอร์มจะไม่สกัดกั้นการเรียกโดยตรงจาก Java ไปยัง
loadClass()
หรือไม่ตรวจสอบ
ผลลัพธ์ของการโทรดังกล่าว ลักษณะการทำงานนี้ไม่ควรส่งผลต่อการทำงานของลักษณะการทำงานที่ดี
เครื่องมือโหลดคลาส
แพลตฟอร์มจะตรวจสอบว่าตัวบอกคลาสที่ตัวโหลดคลาสแสดงผล
ตรงกับข้อบ่งชี้ที่คาดหวัง หากข้อบ่งชี้ที่ส่งกลับไม่ตรงกัน
แพลตฟอร์มมีข้อผิดพลาด NoClassDefFoundError
และจัดเก็บ
ข้อยกเว้นของข้อความโดยละเอียดที่ระบุความคลาดเคลื่อนดังกล่าว
แพลตฟอร์มยังตรวจสอบด้วยว่าข้อบ่งชี้ของคลาสที่ขอนั้นถูกต้อง ช่วงเวลานี้
Check จะตรวจจับการเรียกใช้ JNI ที่โหลดคลาสโดยอ้อม เช่น GetFieldID()
การส่งต่อข้อบ่งชี้ที่ไม่ถูกต้องไปยังคลาสเหล่านั้น เช่น ช่องที่มีลายเซ็น
ไม่พบ java/lang/String
เนื่องจากลายเซ็นดังกล่าวไม่ถูกต้อง
ควรเป็น Ljava/lang/String;
ซึ่งแตกต่างจากการโทรจาก JNI ไปยัง FindClass()
โดยที่ java/lang/String
เป็นชื่อที่มีคุณสมบัติครบถ้วนที่ถูกต้อง
Android 8.0 (API ระดับ 26) ไม่รองรับการมีตัวโหลดคลาสหลายรายการที่พยายามกำหนดคลาส
โดยใช้ออบเจ็กต์ DexFile เดียวกัน การพยายามดำเนินการดังกล่าวจะทำให้รันไทม์ของ Android แสดงข้อผิดพลาด
InternalError
มีข้อความ "พยายามลงทะเบียนไฟล์ dex<filename>
"
ที่มีตัวโหลดหลายคลาส"
เราได้เลิกใช้งาน DexFile API แล้ว เราขอแนะนำให้คุณใช้
หนึ่งใน Classloader ของแพลตฟอร์ม รวมถึง PathClassLoader
หรือ
BaseDexClassLoader
แทน
หมายเหตุ: คุณสามารถสร้างตัวโหลดคลาสหลายรายการที่อ้างอิงถึง
APK หรือคอนเทนเนอร์ไฟล์ JAR เดียวกันจากระบบไฟล์ ตามปกติแล้วการดําเนินการดังกล่าวจะไม่
ทำให้โอเวอร์เฮดหน่วยความจำมาก: หากเก็บไฟล์ DEX ในคอนเทนเนอร์แทนที่จะจัดเก็บ
บีบอัดแล้ว แพลตฟอร์มสามารถดำเนินการ mmap
กับไฟล์ได้แทนที่
ดึงข้อมูลโดยตรง แต่หากแพลตฟอร์มต้องแยกไฟล์ DEX จากคอนเทนเนอร์
การอ้างอิงไฟล์ DEX ในลักษณะนี้อาจใช้หน่วยความจำมาก
ใน Android ตัวโหลดคลาสทั้งหมดจะถือว่าใช้งานได้พร้อมกัน เมื่อชุดข้อความหลายรายการแข่งขันกันในการโหลดคลาสเดียวกันโดยใช้คลาสเดียวกัน ตัวโหลด เทรดแรกที่ดำเนินการสำเร็จจะชนะ และผลลัพธ์จะนำไปใช้ ชุดข้อความอื่นๆ การทำงานลักษณะนี้จะเกิดขึ้นไม่ว่าตัวโหลดคลาสจะเป็นตัวโหลดหรือไม่ก็ตาม แสดงผลคลาสเดียวกัน แสดงผลคลาสอื่น หรือส่งข้อยกเว้น แพลตฟอร์มจะไม่ดำเนินการใดๆ กับข้อยกเว้นดังกล่าว
ข้อควรระวัง: ในเวอร์ชันต่างๆ ของแพลตฟอร์ม Android 8.0 (API ระดับ 26) ต่ำกว่า Android 8.0 (API ระดับ 26) การคาดคะเนเหล่านี้อาจนำไปสู่การระบุ หลายครั้ง ฮีปเสียหายเพราะเกิดความสับสน และผลกระทบที่ไม่พึงประสงค์อื่นๆ