นอกจากฟีเจอร์และความสามารถใหม่ๆ แล้ว Android 7.0 ยังมีการเปลี่ยนแปลงลักษณะการทำงานของระบบและ API ที่หลากหลายด้วย เอกสารนี้จะไฮไลต์การเปลี่ยนแปลงที่สำคัญบางอย่างที่คุณควรทำความเข้าใจและพิจารณาในแอป
หากคุณเคยเผยแพร่แอปสำหรับ Android โปรดทราบว่าแอปของคุณอาจได้รับผลกระทบจากการเปลี่ยนแปลงเหล่านี้ในแพลตฟอร์ม
แบตเตอรี่และหน่วยความจำ
Android 7.0 มีการเปลี่ยนแปลงลักษณะการทำงานของระบบที่มุ่งปรับปรุงระยะเวลาการใช้งานแบตเตอรี่ของอุปกรณ์และลดการใช้ RAM การเปลี่ยนแปลงเหล่านี้อาจส่งผลต่อสิทธิ์เข้าถึงทรัพยากรระบบของแอป รวมถึงวิธีที่แอปโต้ตอบกับแอปอื่นๆ โดยใช้ Intent โดยนัยบางอย่าง
Doze
โหมด Doze ซึ่งเปิดตัวใน Android 6.0 (ระดับ API 23) ช่วยยืดระยะเวลาการใช้งานแบตเตอรี่โดยเลื่อนกิจกรรมของ CPU และกิจกรรมเครือข่ายออกไปเมื่อผู้ใช้ไม่ได้เสียบปลั๊กอุปกรณ์ ไม่ได้เคลื่อนย้าย และปิดหน้าจอไว้ Android 7.0 ได้ปรับปรุงโหมด Doze เพิ่มเติมโดยใช้ชุดย่อยของข้อจำกัด CPU และเครือข่ายขณะที่ไม่ได้เสียบปลั๊กอุปกรณ์และปิดหน้าจอไว้ แต่ไม่จำเป็นต้องอยู่นิ่ง เช่น เมื่อโทรศัพท์มือถืออยู่ในกระเป๋าของผู้ใช้
รูปที่ 1 ภาพแสดงวิธีที่ Doze ใช้ข้อจำกัดกิจกรรมของระบบระดับแรกเพื่อปรับปรุงระยะเวลาการใช้งานแบตเตอรี่
เมื่ออุปกรณ์ใช้พลังงานจากแบตเตอรี่และหน้าจอปิดเป็นระยะเวลาหนึ่ง อุปกรณ์จะเข้าสู่โหมด Doze และใช้ข้อจำกัดชุดย่อยชุดแรก ซึ่งจะปิดการเข้าถึงเครือข่ายของแอป รวมถึงเลื่อนงานและการซิงค์ออกไป หากอุปกรณ์อยู่กับที่เป็นระยะเวลาหนึ่งหลังจากเข้าสู่โหมด Doze ระบบจะใช้ข้อจำกัดที่เหลือของโหมด Doze กับ PowerManager.WakeLock, การปลุก AlarmManager, GPS และการสแกน Wi-Fi ไม่ว่าจะใช้ข้อจำกัดโหมด Doze บางส่วนหรือทั้งหมด ระบบจะปลุกอุปกรณ์เพื่อเข้าสู่ช่วงเวลาบำรุงรักษาสั้นๆ ซึ่งในระหว่างนั้นแอปพลิเคชันจะได้รับอนุญาตให้เข้าถึงเครือข่ายและสามารถดำเนินการงาน/การซิงค์ที่เลื่อนออกไปได้
รูปที่ 2 ภาพแสดงวิธีที่ Doze ใช้ข้อจำกัดกิจกรรมของระบบระดับที่ 2 หลังจากที่อุปกรณ์ไม่มีการเคลื่อนไหวเป็นระยะเวลาหนึ่ง
โปรดทราบว่าการเปิดหน้าจอหรือเสียบปลั๊กอุปกรณ์จะเป็นการออกจากโหมด Doze และนำข้อจำกัดในการประมวลผลเหล่านี้ออก ลักษณะการทำงานเพิ่มเติมนี้ไม่ส่งผลต่อคำแนะนำและแนวทางปฏิบัติแนะนำในการปรับแอปให้เข้ากับโหมด Doze เวอร์ชันก่อนหน้าที่เปิดตัวใน Android 6.0 (ระดับ API 23) ตามที่กล่าวถึงในการเพิ่มประสิทธิภาพสำหรับโหมด Doze และสแตนด์บายแอป คุณยังคงควรทำตามคำแนะนำเหล่านั้น เช่น การใช้ Firebase Cloud Messaging (FCM) เพื่อส่งและรับข้อความ และเริ่มวางแผนการอัปเดตเพื่อรองรับลักษณะการทำงานเพิ่มเติมของโหมด Doze
Project Svelte: การเพิ่มประสิทธิภาพในเบื้องหลัง
Android 7.0 นำการกระจายข้อมูลแบบไม่เจาะจงปลายทาง 3 รายการออกเพื่อช่วยเพิ่มประสิทธิภาพทั้งการใช้หน่วยความจำและการใช้พลังงาน การเปลี่ยนแปลงนี้จำเป็นเนื่องจากการกระจายข้อมูลแบบไม่เจาะจงปลายทางมักจะเริ่มแอปที่ลงทะเบียนเพื่อฟังการกระจายข้อมูลในเบื้องหลัง การนำการออกอากาศเหล่านี้ออกจะช่วยปรับปรุงประสิทธิภาพของอุปกรณ์และประสบการณ์ของผู้ใช้ได้อย่างมาก
อุปกรณ์เคลื่อนที่มีการเปลี่ยนแปลงการเชื่อมต่อบ่อยครั้ง เช่น เมื่อสลับไปมาระหว่าง Wi-Fi กับอินเทอร์เน็ตมือถือ ปัจจุบัน แอปสามารถตรวจสอบการเปลี่ยนแปลงในการเชื่อมต่อได้โดยการลงทะเบียนตัวรับสัญญาณสำหรับการกระจายข้อมูลแบบไม่เจาะจงปลายทาง CONNECTIVITY_ACTION ในไฟล์ Manifest เนื่องจากมีแอปจำนวนมากที่ลงทะเบียนเพื่อรับการออกอากาศนี้ สวิตช์เครือข่ายเพียงครั้งเดียวจึงอาจทำให้แอปทั้งหมดตื่นขึ้นมาและประมวลผลการออกอากาศพร้อมกัน
ในทำนองเดียวกัน ใน Android เวอร์ชันก่อนหน้า แอปสามารถลงทะเบียนเพื่อรับการออกอากาศ ACTION_NEW_PICTURE และ ACTION_NEW_VIDEO โดยนัยจากแอปอื่นๆ เช่น กล้อง เมื่อผู้ใช้ถ่ายภาพด้วยแอปกล้องถ่ายรูป แอปเหล่านี้จะเริ่มทำงานเพื่อประมวลผลการออกอากาศ
เพื่อบรรเทาปัญหาเหล่านี้ Android 7.0 จึงใช้การเพิ่มประสิทธิภาพต่อไปนี้
- แอปที่กำหนดเป้าหมายเป็น Android 7.0 (ระดับ API 24) ขึ้นไปจะไม่ได้รับการออกอากาศ
CONNECTIVITY_ACTIONหากประกาศ Broadcast Receiver ในไฟล์ Manifest แอปจะยังคงได้รับการออกอากาศCONNECTIVITY_ACTIONหากลงทะเบียนBroadcastReceiverด้วยContext.registerReceiver()และบริบทนั้นยังคงถูกต้อง - ระบบจะไม่ส่งการประกาศ
ACTION_NEW_PICTUREหรือACTION_NEW_VIDEOอีกต่อไป การเพิ่มประสิทธิภาพนี้ส่งผลต่อแอปทั้งหมด ไม่ใช่เฉพาะแอปที่กำหนดเป้าหมายเป็น Android 7.0
หากแอปของคุณใช้ Intent เหล่านี้ คุณควรนำทรัพยากร Dependency ออกโดยเร็วที่สุดเพื่อให้กำหนดเป้าหมายอุปกรณ์ Android 7.0 ได้อย่างเหมาะสม
เฟรมเวิร์ก Android มีโซลูชันหลายอย่างเพื่อลดความจำเป็นในการใช้การกระจายข้อมูลแบบไม่เจาะจงปลายทางเหล่านี้ ตัวอย่างเช่น JobScheduler API มีกลไกที่มีประสิทธิภาพในการกำหนดเวลาการทำงานของเครือข่ายเมื่อเป็นไปตามเงื่อนไขที่ระบุ เช่น การเชื่อมต่อกับเครือข่ายที่ไม่มีการวัดปริมาณอินเทอร์เน็ต คุณยังใช้ JobScheduler เพื่อตอบสนองต่อการเปลี่ยนแปลงใน Content Provider ได้ด้วย
ดูข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มประสิทธิภาพเบื้องหลังใน Android 7.0 (ระดับ API 24) และวิธีปรับแอปได้ที่การเพิ่มประสิทธิภาพเบื้องหลัง
การเปลี่ยนแปลงสิทธิ์
Android 7.0 มีการเปลี่ยนแปลงสิทธิ์ที่อาจส่งผลต่อแอปของคุณ
การเปลี่ยนแปลงสิทธิ์ของระบบไฟล์
เพื่อปรับปรุงความปลอดภัยของไฟล์ส่วนตัว ไดเรกทอรีส่วนตัวของแอปที่กำหนดเป้าหมายเป็น Android 7.0 ขึ้นไปจึงมีการจำกัดการเข้าถึง (0700) การตั้งค่านี้จะป้องกันการรั่วไหลของข้อมูลเมตาของไฟล์ส่วนตัว เช่น ขนาดหรือการมีอยู่ของไฟล์ การเปลี่ยนแปลงสิทธิ์นี้มีผลข้างเคียงหลายประการ ดังนี้
-
เจ้าของไม่ควรผ่อนปรนสิทธิ์ในไฟล์ของไฟล์ส่วนตัวอีกต่อไป และการพยายามดำเนินการดังกล่าวโดยใช้
MODE_WORLD_READABLEและ/หรือMODE_WORLD_WRITEABLEจะทริกเกอร์SecurityExceptionหมายเหตุ: ปัจจุบันข้อจำกัดนี้ยังไม่มีการบังคับใช้อย่างเต็มรูปแบบ แอปอาจยังคงแก้ไขสิทธิ์ในไดเรกทอรีส่วนตัวโดยใช้ API แบบเนทีฟหรือ
FileAPI อย่างไรก็ตาม เราไม่แนะนำให้ผ่อนปรนสิทธิ์ในไดเรกทอรีส่วนตัว -
การส่ง URI
file://นอกโดเมนแพ็กเกจอาจทำให้ผู้รับมีเส้นทางที่เข้าถึงไม่ได้ ดังนั้น การพยายามส่งfile://URI จะทริกเกอร์FileUriExposedExceptionวิธีที่แนะนำในการแชร์เนื้อหาของไฟล์ส่วนตัวคือการใช้FileProvider -
DownloadManagerจะแชร์ไฟล์ที่จัดเก็บแบบส่วนตัวตามชื่อไฟล์ไม่ได้อีกต่อไป แอปพลิเคชันเดิมอาจมีเส้นทางที่เข้าถึงไม่ได้เมื่อเข้าถึงCOLUMN_LOCAL_FILENAMEแอปที่กำหนดเป้าหมายเป็น Android 7.0 ขึ้นไปจะเรียกใช้SecurityExceptionเมื่อพยายามเข้าถึงCOLUMN_LOCAL_FILENAMEแอปพลิเคชันเดิมที่ตั้งค่าตำแหน่งการดาวน์โหลดเป็นตำแหน่งสาธารณะโดยใช้DownloadManager.Request.setDestinationInExternalFilesDir()หรือDownloadManager.Request.setDestinationInExternalPublicDir()จะยังคงเข้าถึงเส้นทางในCOLUMN_LOCAL_FILENAMEได้ แต่เราไม่แนะนำให้ใช้วิธีนี้ วิธีที่แนะนำในการเข้าถึงไฟล์ที่DownloadManagerแสดงคือการใช้ContentResolver.openFileDescriptor()
การแชร์ไฟล์ระหว่างแอป
สำหรับแอปที่กำหนดเป้าหมายเป็น Android 7.0 เฟรมเวิร์ก Android จะบังคับใช้นโยบาย API StrictMode ที่ห้ามไม่ให้เปิดเผย URI file:// นอกแอป หาก Intent ที่มี URI ของไฟล์ออกจากแอป แอปจะทำงานไม่สำเร็จโดยมีข้อยกเว้น FileUriExposedException
หากต้องการแชร์ไฟล์ระหว่างแอปพลิเคชัน คุณควรส่ง URI content:// และให้สิทธิ์เข้าถึงชั่วคราวใน URI วิธีที่ง่ายที่สุดในการให้สิทธิ์นี้คือการใช้คลาส FileProvider ดูข้อมูลเพิ่มเติมเกี่ยวกับสิทธิ์และการแชร์ไฟล์ได้ที่หัวข้อการแชร์ไฟล์
การปรับปรุงการเข้าถึง
Android 7.0 มีการเปลี่ยนแปลงที่มุ่งปรับปรุงความสามารถในการใช้งานแพลตฟอร์มสำหรับผู้ใช้ที่มีสายตาเลือนรางหรือมีความบกพร่องทางการมองเห็น โดยทั่วไปแล้ว การเปลี่ยนแปลงเหล่านี้ไม่จำเป็นต้องมีการเปลี่ยนแปลงโค้ดในแอป อย่างไรก็ตาม คุณควรตรวจสอบฟีเจอร์เหล่านี้และทดสอบกับแอปเพื่อประเมินผลกระทบที่อาจเกิดขึ้นกับประสบการณ์ของผู้ใช้
การซูมหน้าจอ
Android 7.0 ช่วยให้ผู้ใช้ตั้งค่าขนาดการแสดงผลซึ่งจะขยายหรือย่อองค์ประกอบทั้งหมดบนหน้าจอได้ จึงช่วยปรับปรุงการช่วยเหลือพิเศษของอุปกรณ์สำหรับผู้ใช้ที่มีสายตาเลือนราง ผู้ใช้ไม่สามารถซูมหน้าจอเกินความกว้างหน้าจอขั้นต่ำที่ sw320dp ซึ่งเป็นความกว้างของ Nexus 4 ซึ่งเป็นโทรศัพท์ขนาดกลางที่พบได้ทั่วไป
รูปที่ 3 หน้าจอทางด้านขวาแสดงผลของการเพิ่มขนาดการแสดงผลของอุปกรณ์ที่ใช้ภาพระบบ Android 7.0
เมื่อความหนาแน่นของอุปกรณ์เปลี่ยนแปลง ระบบจะแจ้งเตือนแอปที่ทำงานอยู่ด้วยวิธีต่อไปนี้
- หากแอปกำหนดเป้าหมายเป็น API ระดับ 23 หรือต่ำกว่า ระบบจะหยุดกระบวนการเบื้องหลังทั้งหมดโดยอัตโนมัติ ซึ่งหมายความว่าหากผู้ใช้ออกจากแอปดังกล่าวเพื่อเปิดหน้าจอการตั้งค่าและเปลี่ยนการตั้งค่าขนาดการแสดงผล ระบบจะปิดแอปในลักษณะเดียวกับที่ทำในสถานการณ์ที่หน่วยความจำเหลือน้อย หากแอปมีกระบวนการทำงานอยู่เบื้องหน้า ระบบจะแจ้งกระบวนการเหล่านั้นเกี่ยวกับการเปลี่ยนแปลงการกำหนดค่าตามที่อธิบายไว้ในการจัดการการเปลี่ยนแปลงรันไทม์ เช่นเดียวกับกรณีที่การวางแนวของอุปกรณ์มีการเปลี่ยนแปลง
- หากแอปกำหนดเป้าหมายเป็น Android 7.0 กระบวนการทั้งหมด (เบื้องหน้าและเบื้องหลัง) จะได้รับแจ้งการเปลี่ยนแปลงการกำหนดค่าตามที่อธิบายไว้ในการจัดการการเปลี่ยนแปลงรันไทม์
แอปส่วนใหญ่ไม่จำเป็นต้องทำการเปลี่ยนแปลงใดๆ เพื่อรองรับฟีเจอร์นี้ หากแอปเป็นไปตามแนวทางปฏิบัติแนะนำของ Android สิ่งที่ต้องตรวจสอบเป็นการเฉพาะมีดังนี้
- ทดสอบแอปบนอุปกรณ์ที่มีความกว้างหน้าจอ
sw320dpและตรวจสอบว่าแอปทำงานได้อย่างเหมาะสม - เมื่อการกำหนดค่าอุปกรณ์เปลี่ยนแปลง ให้อัปเดตข้อมูลที่แคชไว้ซึ่งขึ้นอยู่กับความหนาแน่น เช่น บิตแมปที่แคชไว้หรือทรัพยากรที่โหลดจากเครือข่าย ตรวจสอบการเปลี่ยนแปลงการกำหนดค่าเมื่อแอปกลับมาทำงานอีกครั้งจากสถานะหยุดชั่วคราว
หมายเหตุ: หากคุณแคชข้อมูลที่ขึ้นอยู่กับการกำหนดค่า คุณควรใส่ข้อมูลเมตาที่เกี่ยวข้อง เช่น ขนาดหน้าจอหรือความหนาแน่นของพิกเซลที่เหมาะสมสำหรับข้อมูลนั้น การบันทึกข้อมูลเมตานี้ช่วยให้คุณตัดสินใจได้ว่าต้องรีเฟรชข้อมูลที่แคชไว้หลังจากการเปลี่ยนแปลงการกำหนดค่าหรือไม่
- หลีกเลี่ยงการระบุขนาดด้วยหน่วย px เนื่องจากไม่ได้ปรับขนาดตามความหนาแน่นของหน้าจอ แต่ให้ระบุขนาดด้วยหน่วยความหนาแน่นของพิกเซลอิสระ (
dp) แทน
การตั้งค่าการมองเห็นในวิซาร์ดการตั้งค่า
Android 7.0 มีการตั้งค่าการมองเห็นในหน้าจอต้อนรับ ซึ่งผู้ใช้สามารถตั้งค่าการช่วยเหลือพิเศษต่อไปนี้ในอุปกรณ์ใหม่ได้ ได้แก่ ท่าทางการขยาย, ขนาดแบบอักษร, ขนาดการแสดงผล และ TalkBack การเปลี่ยนแปลงนี้จะเพิ่มระดับการมองเห็นข้อบกพร่องที่เกี่ยวข้องกับการตั้งค่าหน้าจอต่างๆ หากต้องการประเมินผลกระทบของฟีเจอร์นี้ คุณควรทดสอบแอปโดยเปิดใช้การตั้งค่าเหล่านี้ คุณดูการตั้งค่าได้ในส่วนการตั้งค่า > การช่วยเหลือพิเศษ
แอป NDK ที่ลิงก์กับไลบรารีแพลตฟอร์ม
ตั้งแต่ Android 7.0 เป็นต้นไป ระบบจะป้องกันไม่ให้แอปเชื่อมโยงแบบไดนามิกกับไลบรารีที่ไม่ใช่ NDK ซึ่งอาจทำให้แอปขัดข้อง การเปลี่ยนแปลงลักษณะการทำงานนี้มีจุดประสงค์เพื่อสร้างประสบการณ์การใช้งานแอปที่สอดคล้องกันในการอัปเดตแพลตฟอร์มและอุปกรณ์ต่างๆ แม้ว่าโค้ดของคุณอาจไม่ได้ลิงก์กับไลบรารีส่วนตัว แต่ก็เป็นไปได้ว่าไลบรารีแบบคงที่ของบุคคลที่สามในแอปอาจลิงก์อยู่ ดังนั้นนักพัฒนาแอปทุกคนควรตรวจสอบให้แน่ใจว่าแอปของตนไม่ขัดข้องในอุปกรณ์ที่ใช้ Android 7.0 หากแอปใช้โค้ดแบบเนทีฟ คุณควรใช้เฉพาะ NDK API สาธารณะเท่านั้น
แอปของคุณอาจพยายามเข้าถึง API แพลตฟอร์มส่วนตัวได้ 3 วิธี ดังนี้
- แอปของคุณเข้าถึงไลบรารีแพลตฟอร์มส่วนตัวโดยตรง คุณควรอัปเดตแอปให้มีสำเนาของไลบรารีเหล่านั้นเป็นของตัวเอง หรือใช้ NDK API สาธารณะ
- แอปของคุณใช้ไลบรารีของบุคคลที่สามที่เข้าถึงไลบรารีแพลตฟอร์มส่วนตัว แม้ว่าคุณจะแน่ใจว่าแอปไม่ได้เข้าถึงไลบรารีส่วนตัวโดยตรง แต่ก็ควรทดสอบแอปสำหรับสถานการณ์นี้ด้วย
- แอปของคุณอ้างอิงถึงไลบรารีที่ไม่ได้รวมอยู่ใน APK ตัวอย่างเช่น กรณีนี้อาจเกิดขึ้นหากคุณพยายามใช้สำเนา OpenSSL ของคุณเอง แต่ลืมรวมไว้กับ APK ของแอป แอปอาจทำงานได้ตามปกติในแพลตฟอร์ม Android เวอร์ชันที่มี
libcrypto.soอย่างไรก็ตาม แอปอาจขัดข้องใน Android เวอร์ชันใหม่ๆ ที่ไม่มีไลบรารีนี้ (เช่น Android 6.0 ขึ้นไป) วิธีแก้ไขปัญหานี้คือตรวจสอบว่าคุณรวมไลบรารีที่ไม่ใช่ NDK ทั้งหมดไว้กับ APK
แอปไม่ควรใช้ไลบรารีแบบเนทีฟที่ไม่ได้รวมอยู่ใน NDK เนื่องจากไลบรารีดังกล่าวอาจมีการเปลี่ยนแปลงหรือถูกนำออกระหว่าง Android เวอร์ชันต่างๆ การเปลี่ยนจาก OpenSSL เป็น BoringSSL เป็นตัวอย่างหนึ่งของการเปลี่ยนแปลงดังกล่าว นอกจากนี้ เนื่องจากไม่มีข้อกำหนดด้านความเข้ากันได้สำหรับไลบรารีแพลตฟอร์มที่ไม่ได้รวมอยู่ใน NDK อุปกรณ์แต่ละเครื่องจึงอาจให้ความเข้ากันได้ในระดับที่แตกต่างกัน
เพื่อลดผลกระทบที่ข้อจำกัดนี้อาจมีต่อแอปที่เผยแพร่อยู่ในปัจจุบัน ชุดไลบรารีที่มีการใช้งานอย่างมาก เช่น libandroid_runtime.so, libcutils.so, libcrypto.so และ libssl.so จะเข้าถึงได้ชั่วคราวใน Android 7.0 (API ระดับ 24) สำหรับแอปที่กำหนดเป้าหมายเป็น API ระดับ 23 หรือต่ำกว่า หากแอปโหลดไลบรารีเหล่านี้ ไลบรารี logcat จะสร้างคำเตือนและข้อความโทสต์จะปรากฏในอุปกรณ์เป้าหมายเพื่อแจ้งให้คุณทราบ หากเห็นคำเตือนเหล่านี้ คุณควรอัปเดตแอปให้รวมสำเนาของไลบรารีเหล่านั้นไว้ด้วย หรือใช้เฉพาะ NDK API สาธารณะเท่านั้น แพลตฟอร์ม Android เวอร์ชันในอนาคตอาจจำกัดการใช้ไลบรารีส่วนตัวทั้งหมดและทำให้แอปขัดข้อง
แอปทั้งหมดจะสร้างข้อผิดพลาดขณะรันไทม์เมื่อเรียกใช้ API ที่ไม่ใช่แบบสาธารณะหรือเข้าถึงได้ชั่วคราว ผลลัพธ์คือทั้ง System.loadLibrary และ dlopen(3) จะแสดงผลเป็น NULL และอาจทำให้แอปขัดข้อง คุณควรตรวจสอบโค้ดของแอปเพื่อนำการใช้ API ของแพลตฟอร์มส่วนตัวออก และทดสอบแอปอย่างละเอียดโดยใช้อุปกรณ์หรือโปรแกรมจำลองที่ใช้ Android 7.0 (ระดับ API 24) หากไม่แน่ใจว่าแอปใช้ไลบรารีส่วนตัวหรือไม่ คุณสามารถตรวจสอบ logcat เพื่อระบุข้อผิดพลาดขณะรันไทม์ได้
ตารางต่อไปนี้อธิบายลักษณะการทำงานที่คุณควรคาดหวังว่าจะได้เห็นจากแอป โดยขึ้นอยู่กับการใช้ไลบรารีแบบเนทีฟส่วนตัวและระดับ API เป้าหมาย (android:targetSdkVersion)
| ห้องสมุด | ระดับ API เป้าหมาย | สิทธิ์เข้าถึงรันไทม์โดยใช้ Linker แบบไดนามิก | ลักษณะการทำงานของ Android 7.0 (ระดับ API 24) | ลักษณะการทำงานของแพลตฟอร์ม Android ในอนาคต |
|---|---|---|---|---|
| NDK สาธารณะ | ช่วง | รองรับผู้พิการ | ทำงานได้ตามที่คาดไว้ | ทำงานได้ตามที่คาดไว้ |
| ส่วนตัว (ไลบรารีส่วนตัวที่เข้าถึงได้ชั่วคราว) | 23 หรือต่ำกว่า | เข้าถึงได้ชั่วคราว | ทำงานได้ตามที่คาดไว้ แต่คุณจะได้รับคำเตือน Logcat | ข้อผิดพลาดขณะรันไทม์ |
| ส่วนตัว (ไลบรารีส่วนตัวที่เข้าถึงได้ชั่วคราว) | 24 ขึ้นไป | จำกัด | ข้อผิดพลาดขณะรันไทม์ | ข้อผิดพลาดขณะรันไทม์ |
| ส่วนตัว (อื่นๆ) | ช่วง | จำกัด | ข้อผิดพลาดขณะรันไทม์ | ข้อผิดพลาดขณะรันไทม์ |
ตรวจสอบว่าแอปใช้ไลบรารีส่วนตัวหรือไม่
logcat อาจสร้างคำเตือนหรือข้อผิดพลาดขณะรันไทม์เพื่อช่วยคุณระบุปัญหาในการโหลดไลบรารีส่วนตัว ตัวอย่างเช่น หากแอปกำหนดเป้าหมายเป็นระดับ API เป้าหมาย 23 หรือต่ำกว่า และพยายามเข้าถึงไลบรารีส่วนตัวในอุปกรณ์ที่ใช้ Android 7.0 คุณอาจเห็นคำเตือนที่คล้ายกับข้อความต่อไปนี้
03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120
คำเตือน logcat เหล่านี้จะบอกคุณว่าไลบรารีใดกำลังพยายามเข้าถึง API แพลตฟอร์มส่วนตัว แต่จะไม่ทำให้แอปของคุณขัดข้อง อย่างไรก็ตาม หากแอปกำหนดเป้าหมายเป็น API ระดับ 24 ขึ้นไป logcat จะสร้างข้อผิดพลาดขณะรันไทม์ต่อไปนี้และแอปอาจขัดข้อง
java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
at java.lang.Runtime.loadLibrary0(Runtime.java:977)
at java.lang.System.loadLibrary(System.java:1602)
คุณอาจเห็นเอาต์พุต logcat เหล่านี้ด้วยหากแอปใช้ไลบรารีของบุคคลที่สามซึ่งลิงก์กับ API แพลตฟอร์มส่วนตัวแบบไดนามิก เครื่องมือ readelf ใน Android 7.0 NDK ช่วยให้คุณสร้างรายการไลบรารีที่ใช้ร่วมกันซึ่งลิงก์แบบไดนามิกทั้งหมดของไฟล์ .so ที่ระบุได้โดยเรียกใช้คำสั่งต่อไปนี้
aarch64-linux-android-readelf -dW libMyLibrary.so
อัปเดตแอป
ต่อไปนี้คือขั้นตอนบางอย่างที่คุณทำได้เพื่อแก้ไขข้อผิดพลาดประเภทเหล่านี้ และตรวจสอบว่าแอปจะไม่ขัดข้องในการอัปเดตแพลตฟอร์มในอนาคต
- หากแอปใช้ไลบรารีแพลตฟอร์มส่วนตัว คุณควรอัปเดตแอปให้มีสำเนาไลบรารีเหล่านั้นเป็นของตัวเองหรือใช้ NDK API สาธารณะ
- หากแอปใช้ไลบรารีของบุคคลที่สามซึ่งเข้าถึงสัญลักษณ์ส่วนตัว โปรดติดต่อผู้เขียนไลบรารีเพื่ออัปเดตไลบรารี
- ตรวจสอบว่าคุณได้รวมไลบรารีที่ไม่ใช่ NDK ทั้งหมดไว้ใน APK แล้ว
- ใช้ฟังก์ชัน JNI มาตรฐานแทน
getJavaVMและgetJNIEnvจากlibandroid_runtime.so:AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h> AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or JavaVM::AttachCurrentThread from <jni.h>.
- ใช้
__system_property_getแทนสัญลักษณ์property_getส่วนตัวจากlibcutils.soโดยใช้__system_property_getพร้อมกับรายการต่อไปนี้#include <sys/system_properties.h>หมายเหตุ: ความพร้อมใช้งานและเนื้อหาของพร็อพเพอร์ตี้ระบบไม่ได้ทดสอบผ่าน CTS การแก้ไขที่ดีกว่าคือหลีกเลี่ยงการใช้พร็อพเพอร์ตี้เหล่านี้ทั้งหมด
- ใช้สัญลักษณ์
SSL_ctrlเวอร์ชันท้องถิ่นจากlibcrypto.soเช่น คุณควรลิงก์libcyrpto.aแบบคงที่ในไฟล์.soหรือรวมlibcrypto.soเวอร์ชันที่ลิงก์แบบไดนามิกจาก BoringSSL/OpenSSL และรวมไว้ใน APK
Android for Work
Android 7.0 มีการเปลี่ยนแปลงสำหรับแอปที่กำหนดเป้าหมายเป็น Android for Work ซึ่งรวมถึงการเปลี่ยนแปลงการติดตั้งใบรับรอง การรีเซ็ตรหัสผ่าน การจัดการผู้ใช้รอง และการเข้าถึงตัวระบุอุปกรณ์ หากคุณกำลังสร้างแอปสำหรับสภาพแวดล้อม Android for Work คุณควรตรวจสอบการเปลี่ยนแปลงเหล่านี้และแก้ไขแอปตามความเหมาะสม
- คุณต้องติดตั้งโปรแกรมติดตั้งใบรับรองที่ได้รับมอบสิทธิ์ก่อนที่ DPC จะตั้งค่าได้ สำหรับทั้งแอปโปรไฟล์และแอปเจ้าของอุปกรณ์ที่กำหนดเป้าหมายเป็น Android 7.0 (ระดับ API 24) คุณควรติดตั้งโปรแกรมติดตั้งใบรับรองที่ได้รับมอบสิทธิ์ก่อนที่เครื่องมือควบคุมนโยบายด้านอุปกรณ์ (DPC) จะเรียกใช้
DevicePolicyManager.setCertInstallerPackage()หากยังไม่ได้ติดตั้งโปรแกรมติดตั้ง ระบบจะแสดงข้อผิดพลาดIllegalArgumentException - ข้อจำกัดการรีเซ็ตรหัสผ่านสำหรับผู้ดูแลระบบอุปกรณ์จะมีผลกับเจ้าของโปรไฟล์แล้ว ผู้ดูแลระบบอุปกรณ์จะไม่สามารถใช้
DevicePolicyManager.resetPassword()เพื่อล้างรหัสผ่านหรือเปลี่ยนรหัสผ่านที่ตั้งไว้แล้วได้อีกต่อไป ผู้ดูแลระบบอุปกรณ์จะยังคงตั้งรหัสผ่านได้ แต่จะทำได้เฉพาะเมื่ออุปกรณ์ไม่มีรหัสผ่าน, PIN หรือรูปแบบเท่านั้น - เจ้าของอุปกรณ์และโปรไฟล์จะจัดการบัญชีได้แม้ว่าจะมีการตั้งค่าข้อจำกัดไว้ก็ตาม เจ้าของอุปกรณ์และเจ้าของโปรไฟล์สามารถเรียกใช้ Account Management API ได้แม้ว่าจะมีข้อจำกัดของผู้ใช้
DISALLOW_MODIFY_ACCOUNTSอยู่ก็ตาม - เจ้าของอุปกรณ์สามารถจัดการผู้ใช้รองได้ เมื่ออุปกรณ์ทำงานในโหมดเจ้าของอุปกรณ์ ระบบจะตั้งค่าข้อจำกัด
DISALLOW_ADD_USERโดยอัตโนมัติ ซึ่งจะป้องกันไม่ให้ผู้ใช้สร้างผู้ใช้รองที่ไม่มีการจัดการ นอกจากนี้ เมธอดCreateUser()และcreateAndInitializeUser()เลิกใช้งานแล้ว โดยมีเมธอดDevicePolicyManager.createAndManageUser()ใหม่มาแทนที่ - เจ้าของอุปกรณ์จะเข้าถึงตัวระบุอุปกรณ์ได้ เจ้าของอุปกรณ์สามารถเข้าถึงที่อยู่ MAC ของ Wi-Fi ของอุปกรณ์ได้โดยใช้
DevicePolicyManager.getWifiMacAddress()หากไม่เคยเปิดใช้ Wi-Fi ในอุปกรณ์ เมธอดนี้จะแสดงผลค่าเป็นnull - การตั้งค่าโหมดการทำงานจะควบคุมสิทธิ์เข้าถึงแอปงาน เมื่อโหมดงานปิดอยู่ ตัวเปิดระบบจะระบุว่าแอปงานไม่พร้อมใช้งานโดยเปลี่ยนเป็นสีเทา การเปิดใช้โหมดการทำงานอีกครั้งจะคืนค่าลักษณะการทำงานตามปกติ
- เมื่อติดตั้งไฟล์ PKCS #12 ที่มีกลุ่มใบรับรองไคลเอ็นต์และคีย์ส่วนตัวที่เกี่ยวข้องจาก UI การตั้งค่า ระบบจะไม่ติดตั้งใบรับรอง CA ในกลุ่มใบรับรองลงในที่เก็บข้อมูลเข้าสู่ระบบที่เชื่อถือได้อีกต่อไป การดำเนินการนี้จะไม่ส่งผลต่อผลลัพธ์ของ
KeyChain.getCertificateChain()เมื่อแอปพยายามดึงข้อมูลเชนใบรับรองไคลเอ็นต์ในภายหลัง หากจำเป็น ควรติดตั้งใบรับรอง CA ลงในที่เก็บข้อมูลเข้าสู่ระบบที่เชื่อถือได้โดยใช้ UI การตั้งค่าแยกต่างหาก โดยใช้รูปแบบที่เข้ารหัส DER ภายใต้นามสกุลไฟล์ .crt หรือ .cer - ตั้งแต่ Android 7.0 เป็นต้นไป ระบบจะจัดการการลงทะเบียนและการจัดเก็บลายนิ้วมือตามผู้ใช้แต่ละราย หาก Device Policy Client (DPC) ของเจ้าของโปรไฟล์กำหนดเป้าหมายเป็น API ระดับ 23 (หรือต่ำกว่า) ในอุปกรณ์ที่ใช้ Android 7.0 (API ระดับ 24) ผู้ใช้จะยังคงตั้งค่าลายนิ้วมือในอุปกรณ์ได้ แต่แอปพลิเคชันงานจะเข้าถึงลายนิ้วมือของอุปกรณ์ไม่ได้ เมื่อ DPC กำหนดเป้าหมายเป็นระดับ API เป้าหมาย 24 ขึ้นไป ผู้ใช้จะตั้งค่าลายนิ้วมือสำหรับโปรไฟล์งานโดยเฉพาะได้โดยไปที่การตั้งค่า > ความปลอดภัย > ความปลอดภัยของโปรไฟล์งาน
DevicePolicyManager.getStorageEncryptionStatus()จะแสดงสถานะการเข้ารหัสใหม่ENCRYPTION_STATUS_ACTIVE_PER_USERเพื่อระบุว่าการเข้ารหัสทำงานอยู่และคีย์การเข้ารหัสเชื่อมโยงกับผู้ใช้ ระบบจะแสดงสถานะใหม่ก็ต่อเมื่อ DPC กำหนดเป้าหมายเป็น API ระดับ 24 ขึ้นไปเท่านั้น สำหรับแอปที่กำหนดเป้าหมายเป็นระดับ API ก่อนหน้า ระบบจะแสดงผลENCRYPTION_STATUS_ACTIVEแม้ว่าคีย์การเข้ารหัสจะเจาะจงสำหรับผู้ใช้หรือโปรไฟล์ก็ตาม- ใน Android 7.0 เมธอดหลายรายการที่โดยปกติจะส่งผลต่อทั้งอุปกรณ์จะทำงานแตกต่างออกไปหากอุปกรณ์มีโปรไฟล์งานที่ติดตั้งพร้อมกับ Work Challenge แยกต่างหาก วิธีการเหล่านี้จะมีผลกับโปรไฟล์งานเท่านั้น แทนที่จะส่งผลต่ออุปกรณ์ทั้งเครื่อง (ดูรายการเมธอดทั้งหมดได้ในเอกสารประกอบของ
DevicePolicyManager.getParentProfileInstance()) เช่นDevicePolicyManager.lockNow()จะล็อกเฉพาะโปรไฟล์งานแทนที่จะล็อกทั้งอุปกรณ์ สำหรับแต่ละเมธอดเหล่านี้ คุณสามารถรับลักษณะการทำงานเดิมได้โดยเรียกใช้เมธอดในอินสแตนซ์หลักของDevicePolicyManagerคุณสามารถรับอินสแตนซ์หลักนี้ได้โดยเรียกใช้DevicePolicyManager.getParentProfileInstance()ตัวอย่างเช่น หากคุณเรียกใช้เมธอดlockNow()ของอินสแตนซ์หลัก อุปกรณ์ทั้งหมดจะล็อก
การเก็บรักษาคำอธิบายประกอบ
Android 7.0 แก้ไขข้อบกพร่องที่ระบบละเว้นระดับการมองเห็นของคำอธิบายประกอบ ปัญหานี้ทำให้รันไทม์เข้าถึงคำอธิบายประกอบที่ไม่ควรเข้าถึงได้ ซึ่งได้แก่
VISIBILITY_BUILD: มีไว้ให้มองเห็นได้เฉพาะในเวลาบิลด์เท่านั้นVISIBILITY_SYSTEM: มีไว้เพื่อให้มองเห็นได้ขณะรันไทม์ แต่เฉพาะกับระบบที่เกี่ยวข้องเท่านั้น
หากแอปของคุณอาศัยลักษณะการทำงานนี้ ให้เพิ่มนโยบายการเก็บรักษาลงในคำอธิบายประกอบที่ต้องพร้อมใช้งานที่รันไทม์ โดยใช้ @Retention(RetentionPolicy.RUNTIME)
การเปลี่ยนแปลงการกำหนดค่าเริ่มต้นของ TLS/SSL
Android 7.0 มีการเปลี่ยนแปลงต่อไปนี้ในการกำหนดค่า TLS/SSL เริ่มต้นที่แอปใช้สำหรับการรับส่งข้อมูล HTTPS และ TLS/SSL อื่นๆ
- ตอนนี้ชุดการเข้ารหัส RC4 ปิดใช้อยู่
- เปิดใช้ชุดการเข้ารหัส CHACHA20-POLY1305 แล้ว
การปิดใช้ RC4 โดยค่าเริ่มต้นอาจทำให้การเชื่อมต่อ HTTPS หรือ TLS/SSL ขัดข้องเมื่อเซิร์ฟเวอร์ไม่เจรจาต่อรองชุดการเข้ารหัสสมัยใหม่ การแก้ไขที่แนะนำคือการปรับปรุงการกำหนดค่าของเซิร์ฟเวอร์เพื่อเปิดใช้ชุดการเข้ารหัสและโปรโตคอลที่รัดกุมและทันสมัยยิ่งขึ้น โดยหลักการแล้ว ควรเปิดใช้ TLSv1.2 และ AES-GCM และควรเปิดใช้และเลือกใช้ชุดการเข้ารหัส Forward Secrecy (ECDHE)
อีกทางเลือกหนึ่งคือการแก้ไขแอปให้ใช้ SSLSocketFactory ที่กำหนดเองเพื่อสื่อสารกับเซิร์ฟเวอร์ ควรออกแบบโรงงานให้สร้างอินสแตนซ์ SSLSocket ที่เปิดใช้ชุดการเข้ารหัสบางชุดที่เซิร์ฟเวอร์กำหนดไว้นอกเหนือจากชุดการเข้ารหัสเริ่มต้น
หมายเหตุ: การเปลี่ยนแปลงเหล่านี้ไม่เกี่ยวข้องกับ WebView
แอปที่กำหนดเป้าหมายเป็น Android 7.0
การเปลี่ยนแปลงลักษณะการทำงานเหล่านี้มีผลเฉพาะกับแอปที่กำหนดเป้าหมายเป็น Android 7.0 (ระดับ API 24) ขึ้นไปเท่านั้น แอปที่คอมไพล์กับ Android 7.0 หรือตั้งค่า targetSdkVersion เป็น Android 7.0 ขึ้นไปต้องแก้ไขแอปเพื่อรองรับลักษณะการทำงานเหล่านี้อย่างเหมาะสม หากเกี่ยวข้องกับแอป
การเปลี่ยนแปลงการเรียงอันดับ
Android 7.0 (ระดับ API 24) แก้ไขข้อบกพร่องในการคำนวณ serialVersionUID เริ่มต้นซึ่งไม่ตรงกับข้อกำหนดเฉพาะ
คลาสที่ใช้ Serializable และไม่ได้ระบุช่อง serialVersionUID ที่ชัดเจนอาจเห็นการเปลี่ยนแปลงใน serialVersionUID เริ่มต้น ซึ่งจะทำให้เกิดข้อยกเว้นเมื่อพยายามดีซีเรียลไลซ์อินสแตนซ์ของคลาสที่ซีเรียลไลซ์ในเวอร์ชันก่อนหน้าหรือซีเรียลไลซ์โดยแอปที่กำหนดเป้าหมายเป็นเวอร์ชันก่อนหน้า ข้อความแสดงข้อผิดพลาดจะมีลักษณะดังนี้
local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567
การแก้ไขปัญหาเหล่านี้ต้องเพิ่มช่อง serialVersionUID ลงในคลาสที่ได้รับผลกระทบซึ่งมีค่าเป็น stream classdesc
serialVersionUID จากข้อความแสดงข้อผิดพลาด เช่น 1234 ในกรณีนี้ การเปลี่ยนแปลงดังกล่าวเป็นไปตามคำแนะนำแนวทางปฏิบัติแนะนำทั้งหมดสำหรับการเขียนโค้ดการเรียงลำดับข้อมูล และจะใช้ได้กับ Android ทุกเวอร์ชัน
ข้อบกพร่องที่ได้รับการแก้ไขเกี่ยวข้องกับการมีอยู่ของเมธอดตัวเริ่มต้นแบบคงที่ เช่น <clinit> ตามข้อกำหนดเฉพาะ การมีหรือไม่มีเมธอดตัวกำหนดค่าเริ่มต้นแบบคงที่ในคลาสจะส่งผลต่อ serialVersionUID เริ่มต้นที่คำนวณสำหรับคลาสนั้น
ก่อนที่จะแก้ไขข้อบกพร่อง การคำนวณจะตรวจสอบซูเปอร์คลาสเพื่อหาตัวเริ่มต้นแบบคงที่ด้วยหากคลาสไม่มีตัวเริ่มต้นแบบคงที่
โปรดทราบว่าการเปลี่ยนแปลงนี้ไม่ส่งผลต่อแอปที่กำหนดเป้าหมายเป็น API ระดับ 23 หรือต่ำกว่า, คลาสที่มีช่อง serialVersionUID หรือคลาสที่มีเมธอดตัวเริ่มต้นแบบคงที่
ประเด็นสำคัญอื่นๆ
- เมื่อแอปทำงานบน Android 7.0 แต่กำหนดเป้าหมายเป็นระดับ API ที่ต่ำกว่า และผู้ใช้เปลี่ยนขนาดการแสดงผล ระบบจะหยุดกระบวนการของแอป แอปต้องสามารถจัดการสถานการณ์นี้ได้อย่างราบรื่น มิฉะนั้น แอปจะขัดข้องเมื่อผู้ใช้กู้คืนจากรายการล่าสุด
คุณควรทดสอบแอปเพื่อให้แน่ใจว่าลักษณะการทำงานนี้จะไม่เกิดขึ้น ซึ่งทำได้โดยทำให้เกิดข้อขัดข้องที่เหมือนกันเมื่อปิดแอปด้วยตนเองโดยใช้ DDMS
แอปที่กำหนดเป้าหมายเป็น Android 7.0 (ระดับ API 24) ขึ้นไปจะไม่ถูกปิดโดยอัตโนมัติเมื่อความหนาแน่นเปลี่ยนแปลง แต่ก็อาจยังตอบสนองต่อการเปลี่ยนแปลงการกำหนดค่าได้ไม่ดีนัก
- แอปใน Android 7.0 ควรจัดการกับการเปลี่ยนแปลงการกำหนดค่าได้อย่างราบรื่น และไม่ควรขัดข้องเมื่อเริ่มทำงานในครั้งต่อๆ ไป คุณสามารถตรวจสอบลักษณะการทำงานของแอปได้โดยเปลี่ยนขนาดแบบอักษร (การตั้งค่า > การแสดงผล > ขนาดแบบอักษร) แล้วกู้คืนแอปจากรายการล่าสุด
-
เนื่องจากข้อบกพร่องใน Android เวอร์ชันก่อนหน้า ระบบจึงไม่ได้แจ้งว่าการเขียนไปยังซ็อกเก็ต TCP ในเทรดหลักเป็นการละเมิดโหมดเข้มงวด Android 7.0 แก้ไขข้อบกพร่องนี้แล้ว
แอปที่แสดงลักษณะการทำงานนี้จะแสดง
android.os.NetworkOnMainThreadExceptionโดยทั่วไปแล้ว การดำเนินการเครือข่ายในเทรดหลักไม่ใช่แนวทางที่ดีเนื่องจากการดำเนินการเหล่านี้ มักจะมีเวลาในการตอบสนองสูงซึ่งทำให้เกิด ANR และอาการกระตุก -
ตอนนี้เมธอดตระกูล
Debug.startMethodTracing()จะจัดเก็บเอาต์พุตในไดเรกทอรีเฉพาะแพ็กเกจในพื้นที่เก็บข้อมูลที่ใช้ร่วมกันโดยค่าเริ่มต้น แทนที่จะจัดเก็บไว้ที่ระดับบนสุดของการ์ด SD ซึ่งหมายความว่าแอปไม่จำเป็นต้องขอสิทธิ์WRITE_EXTERNAL_STORAGEเพื่อใช้ API เหล่านี้อีกต่อไป -
ตอนนี้ API ของแพลตฟอร์มจำนวนมากเริ่มตรวจสอบเพย์โหลดขนาดใหญ่ที่ส่งผ่านธุรกรรม
Binderและตอนนี้ระบบจะส่งTransactionTooLargeExceptionsอีกครั้งเป็นRuntimeExceptionsแทนที่จะบันทึกหรือระงับโดยไม่แจ้งให้ทราบ ตัวอย่างที่พบบ่อยคือการจัดเก็บข้อมูลมากเกินไปในActivity.onSaveInstanceState()ซึ่งทำให้ActivityThread.StopInfoแสดงRuntimeExceptionเมื่อแอปกำหนดเป้าหมายเป็น Android 7.0 -
หากแอปโพสต์งาน
RunnableไปยังViewและViewไม่ได้แนบกับหน้าต่าง ระบบจะจัดคิวงานRunnableด้วยViewงานRunnableจะไม่ทำงานจนกว่าViewจะแนบกับหน้าต่าง ลักษณะการทำงานนี้จะแก้ไขข้อบกพร่องต่อไปนี้ -
หากแอปใน Android 7.0 ที่มีสิทธิ์
DELETE_PACKAGESพยายามลบแพ็กเกจ แต่แอปอื่นได้ติดตั้งแพ็กเกจนั้นไว้ ระบบจะกำหนดให้ผู้ใช้ยืนยัน ในสถานการณ์นี้ แอปควรคาดหวังว่าSTATUS_PENDING_USER_ACTIONจะเป็นสถานะการแสดงผลเมื่อเรียกใช้PackageInstaller.uninstall() - ผู้ให้บริการ JCA ที่ชื่อ Crypto เลิกใช้งานแล้ว เนื่องจากอัลกอริทึมเดียวของ JCA คือ SHA1PRNG มีการเข้ารหัสที่อ่อนแอ แอปจะไม่สามารถใช้ SHA1PRNG เพื่อรับคีย์ (อย่างไม่ปลอดภัย) ได้อีกต่อไป เนื่องจากผู้ให้บริการรายนี้ไม่พร้อมให้บริการอีกต่อไป ดูข้อมูลเพิ่มเติมได้ที่บล็อกโพสต์ผู้ให้บริการ "Crypto" ด้านความปลอดภัยที่เลิกใช้งานใน Android N