การอัปเดตที่ทํากับพื้นที่เฉพาะของจอแสดงผลมีดังนี้
การตกแต่งระบบ
Android 10 เพิ่มการรองรับการกำหนดค่าจอแสดงผลรองเพื่อแสดงการตกแต่งระบบบางอย่าง เช่น วอลเปเปอร์ แถบนําทาง และ Launcher โดยค่าเริ่มต้น จอแสดงผลหลักจะแสดงการตกแต่งระบบทั้งหมด และจอแสดงผลรองจะแสดงการตกแต่งที่เปิดใช้ไว้ คุณสามารถตั้งค่าการรองรับตัวแก้ไขวิธีการป้อนข้อมูล (IME) แยกจากการตกแต่งระบบอื่นๆ ได้
ใช้ DisplayWindowSettings#setShouldShowSystemDecorsLocked()
เพื่อเพิ่มการรองรับการตกแต่งของระบบในจอแสดงผลที่เฉพาะเจาะจง หรือระบุค่าเริ่มต้นใน /data/system/display_settings.xml
ตัวอย่างเช่น
ดูการตั้งค่าหน้าต่างการแสดงผล
การใช้งาน
DisplayWindowSettings#setShouldShowSystemDecorsLocked()
ก็แสดงใน WindowManager#setShouldShowSystemDecors()
สำหรับการทดสอบด้วย การเปิดใช้งานเมธอดนี้โดยมีเจตนาเพื่อเปิดใช้การตกแต่งระบบจะไม่เพิ่มหน้าต่างการตกแต่งที่ขาดหายไปก่อนหน้านี้ หรือนำหน้าต่างการตกแต่งออกหากมีอยู่แล้วก่อนหน้านี้ ในกรณีส่วนใหญ่ การเปลี่ยนแปลงการรองรับการตกแต่งระบบจะมีผลเต็มที่หลังจากรีบูตอุปกรณ์เท่านั้น
การตรวจสอบการรองรับการตกแต่งของระบบในฐานโค้ด WindowManager มักจะทำผ่าน DisplayContent#supportsSystemDecorations()
ส่วนการตรวจสอบบริการภายนอก (เช่น UI ของระบบเพื่อตรวจสอบว่าควรแสดงแถบนําทางหรือไม่) จะใช้ WindowManager#shouldShowSystemDecors()
หากต้องการทำความเข้าใจสิ่งที่ควบคุมโดยการตั้งค่านี้ ให้ดูจุดเรียกใช้ของวิธีการเหล่านี้
หน้าต่างการตกแต่ง UI ของระบบ
Android 10 เพิ่มการรองรับหน้าต่างการตกแต่งของระบบสำหรับแถบนำทางเท่านั้น เนื่องจากแถบนำทางเป็นสิ่งจำเป็นสำหรับการไปยังส่วนต่างๆ ระหว่างกิจกรรมและแอป โดยค่าเริ่มต้น แถบนำทางจะแสดงตัวเลือก "กลับ" และ "หน้าแรก" ตัวเลือกนี้จะรวมอยู่ด้วยก็ต่อเมื่อจอแสดงผลเป้าหมายรองรับการตกแต่งระบบ (ดู DisplayWindowSettings
)
แถบสถานะ เป็นหน้าต่างระบบที่ซับซ้อนขึ้นเพราะยังมีหน้าต่างแจ้งเตือน การตั้งค่าด่วน และหน้าจอล็อกด้วย ใน Android 10 ระบบไม่รองรับแถบสถานะในจอแสดงผลรอง ดังนั้น การแจ้งเตือน การตั้งค่า และปุ่มกดแบบเต็มจึงใช้ได้เฉพาะในจอแสดงผลหลักเท่านั้น
หน้าจอรองไม่รองรับหน้าต่างระบบภาพรวม/ล่าสุด ใน Android 10 นั้น AOSP จะแสดงเฉพาะ "ล่าสุด" ในจอแสดงผลเริ่มต้นและประกอบด้วยกิจกรรมจากจอแสดงผลทั้งหมด เมื่อเปิดจากรายการล่าสุด ระบบจะแสดงกิจกรรมที่อยู่ในจอแสดงผลรองขึ้นมาที่ด้านหน้าของจอแสดงผลนั้นโดยค่าเริ่มต้น แนวทางนี้มีปัญหาที่ทราบอยู่แล้ว เช่น ไม่อัปเดตทันทีเมื่อแอปปรากฏในหน้าจออื่น
การใช้งาน
หากต้องการใช้ฟีเจอร์ UI ระบบเพิ่มเติม ผู้ผลิตอุปกรณ์ควรใช้คอมโพเนนต์ UI ระบบรายการเดียวที่คอยฟังการเพิ่ม/การนำจอแสดงผลออก และแสดงเนื้อหาที่เหมาะสม
คอมโพเนนต์ UI ของระบบที่รองรับ Multi-Display (MD) ควรจัดการกับกรณีต่อไปนี้
- การเริ่มต้นโฆษณาแบบดิสเพลย์หลายรายการเมื่อเริ่มต้นระบบ
- เพิ่มจอแสดงผลที่รันไทม์
- นำจอแสดงผลออกที่รันไทม์
เมื่อ UI ของระบบตรวจพบการเพิ่มจอแสดงผลก่อน WindowManager ก็จะทำให้เกิดการแข่งขัน ปัญหานี้สามารถหลีกเลี่ยงได้โดยใช้การเรียกกลับที่กําหนดเองจาก WindowManager ไปยัง UI ของระบบเมื่อเพิ่มจอแสดงผลแทนการติดตามเหตุการณ์ของ DisplayManager.DisplayListener
ในการใช้ข้อมูลอ้างอิง โปรดดู CommandQueue.Callbacks#onDisplayReady
สำหรับการรองรับแถบนำทางและ WallpaperManagerInternal#onDisplayReady
สำหรับวอลเปเปอร์
นอกจากนี้ Android 10 ยังมีการอัปเดตต่อไปนี้ด้วย
- คลาส
NavigationBarController
จะควบคุมฟังก์ชันการทำงานทั้งหมดสำหรับแถบนําทางโดยเฉพาะ - ดูแถบนำทางแบบกำหนดเองได้ที่
CarStatusBar
TYPE_NAVIGATION_BAR
ไม่ได้จํากัดไว้ที่อินสแตนซ์เดียวอีกต่อไปและสามารถใช้ต่อจอแสดงผลได้- อัปเดต
IWindowManager#hasNavigationBar()
ให้รวมพารามิเตอร์displayId
สำหรับ UI ของระบบเท่านั้น
ปืนยิงลูกระเบิด
ใน Android 10 จอแสดงผลแต่ละจอที่กําหนดค่าให้รองรับการตกแต่งระบบจะมีกองหน้าสำหรับกิจกรรมของ Launcher ที่มีประเภท WindowConfiguration#ACTIVITY_TYPE_HOME
โดยเฉพาะโดยค่าเริ่มต้น จอแสดงผลแต่ละหน้าจอจะใช้กิจกรรม Launcher แยกกัน
รูปที่ 1 ตัวอย่าง Launcher แบบหลายจอแสดงผลสำหรับ
platform/development/samples/MultiDisplay
โปรแกรมเปิดแอปที่มีอยู่ส่วนใหญ่ไม่รองรับอินสแตนซ์หลายรายการและไม่ได้เพิ่มประสิทธิภาพสำหรับหน้าจอขนาดใหญ่ นอกจากนี้ ผู้ใช้มักคาดหวังประสบการณ์การใช้งานที่แตกต่างออกไปในจอแสดงผลรอง/ภายนอก Android 10 เปิดตัวหมวดหมู่ SECONDARY_HOME
ในตัวกรอง Intent เพื่อมอบกิจกรรมเฉพาะสำหรับหน้าจอรอง ระบบจะใช้อินสแตนซ์ของกิจกรรมนี้ในจอแสดงผลทั้งหมดที่รองรับการตกแต่งของระบบ โดยจะมี 1 อินสแตนซ์ต่อจอแสดงผล
<activity> ... <intent-filter> <category android:name="android.intent.category.SECONDARY_HOME" /> ... </intent-filter> </activity>
กิจกรรมต้องมีโหมดเปิดตัวที่ไม่ป้องกันอินสแตนซ์หลายรายการและต้องปรับให้เข้ากับหน้าจอขนาดต่างๆ โหมดการเริ่มทำงานต้องไม่ใช่ singleInstance
หรือ singleTask
การใช้งาน
ใน Android 10 RootActivityContainer#startHomeOnDisplay()
จะเลือกคอมโพเนนต์และความตั้งใจที่ต้องการโดยอัตโนมัติโดยขึ้นอยู่กับจอแสดงผลที่เปิดหน้าจอหลัก RootActivityContainer#resolveSecondaryHomeActivity()
มีตรรกะในการค้นหาคอมโพเนนต์กิจกรรมของ Launcher โดยขึ้นอยู่กับ Launcher ที่เลือกอยู่ในปัจจุบัน และใช้ค่าเริ่มต้นของระบบได้หากจำเป็น (ดูActivityTaskManagerService#getSecondaryHomeIntent()
)
ข้อจำกัดด้านความปลอดภัย
นอกเหนือจากข้อจำกัดที่มีผลกับกิจกรรมบนจอแสดงผลรองแล้ว โปรแกรมเปิดแอปจะปรากฏเฉพาะในจอแสดงผลเสมือนที่ระบบเป็นเจ้าของเท่านั้น เพื่อหลีกเลี่ยงไม่ให้แอปที่เป็นอันตรายสร้างจอแสดงผลเสมือนที่เปิดใช้การตกแต่งระบบและอ่านข้อมูลที่ละเอียดอ่อนของผู้ใช้จากแพลตฟอร์ม โปรแกรมเปิดไม่แสดงเนื้อหาบนจอแสดงผลเสมือนจริงที่ไม่ใช่ของระบบ
วอลเปเปอร์
ใน Android 10 (และเวอร์ชันที่ใหม่กว่า) ระบบจะรองรับวอลเปเปอร์ในจอแสดงผลรอง ดังนี้
รูปที่ 2 วอลเปเปอร์เคลื่อนไหวบนจอแสดงผลภายใน (ด้านบน) และภายนอก (ด้านล่าง)
นักพัฒนาแอปสามารถประกาศการรองรับฟีเจอร์วอลเปเปอร์ได้โดยระบุ
android:supportsMultipleDisplays="true"
ในคำจำกัดความ XML ของ
WallpaperInfo
นอกจากนี้ นักพัฒนาวอลเปเปอร์ยังควรโหลดชิ้นงานโดยใช้บริบทการแสดงผลใน WallpaperService.Engine#getDisplayContext()
ด้วย
เฟรมเวิร์กจะสร้างอินสแตนซ์ WallpaperService.Engine
1 รายการต่อจอแสดงผล เครื่องมือแต่ละรายการจึงมีบริบทของแพลตฟอร์มและการแสดงผลเป็นของตัวเอง นักพัฒนาแอปต้องตรวจสอบว่าแต่ละเอนจิ้นวาดภาพได้แบบอิสระด้วยอัตราเฟรมที่แตกต่างกัน โดยคำนึงถึง VSYNC
เลือกวอลเปเปอร์สำหรับแต่ละหน้าจอ
Android 10 ไม่มีการรองรับแพลตฟอร์มโดยตรงสำหรับการเลือกวอลเปเปอร์สำหรับแต่ละหน้าจอ ในการทำเช่นนี้ ต้องมีตัวระบุการแสดงผลที่เสถียร
เพื่อคงการตั้งค่าวอลเปเปอร์ต่อจอแสดงผล
Display#getDisplayId()
เป็นแบบไดนามิก ไม่มีการรับประกันว่าจอแสดงผลจริงจะมีรหัสเดียวกันหลังจากรีบูต
อย่างไรก็ตาม Android 10 ได้เพิ่ม DisplayInfo.mAddress
ซึ่งมีตัวระบุแบบคงที่สำหรับจอแสดงผลของอุปกรณ์จริงและจะนำไปใช้งานอย่างเต็มรูปแบบในอนาคตได้ น่าเสียดายที่ตอนนี้สายเกินไปแล้ว
ที่จะใช้ตรรกะสำหรับ Android 10 วิธีแก้ปัญหาที่แนะนำ
- ใช้
WallpaperManager
API เพื่อตั้งค่าวอลเปเปอร์ WallpaperManager
มาจากออบเจ็กต์Context
และออบเจ็กต์Context
แต่ละรายการมีข้อมูลเกี่ยวกับการแสดงผลที่เกี่ยวข้อง (Context#getDisplay()/getDisplayId()
) คุณจึงรับdisplayId
จากอินสแตนซ์WallpaperManager
ได้โดยไม่ต้องเพิ่มเมธอดใหม่- ในส่วนเฟรมเวิร์ก ให้ใช้
displayId
ที่ได้มาจากออบเจ็กต์Context
แล้วจับคู่กับตัวระบุแบบคงที่ (เช่น พอร์ตของจอแสดงผลจริง) ใช้ตัวระบุแบบคงที่เพื่อเก็บวอลเปเปอร์ที่เลือกไว้
วิธีแก้ปัญหานี้ใช้การติดตั้งใช้งานที่มีอยู่แล้วสำหรับเครื่องมือเลือกวอลเปเปอร์ หากเปิดแอปในจอแสดงผลที่เฉพาะเจาะจงและใช้บริบทที่เหมาะสม เมื่อแอปเรียกให้ตั้งค่าวอลเปเปอร์ ระบบจะระบุจอแสดงผลได้โดยอัตโนมัติ
หากจำเป็นต้องตั้งค่าวอลเปเปอร์สำหรับจอแสดงผลอื่นนอกเหนือจากจอแสดงผลปัจจุบัน ให้สร้างออบเจ็กต์ Context
ใหม่สำหรับจอแสดงผลเป้าหมาย (Context#createDisplayContext
) และรับอินสแตนซ์ WallpaperManager
จากจอแสดงผลนั้น
ข้อจำกัดด้านความปลอดภัย
ระบบจะไม่แสดงวอลเปเปอร์บนจอแสดงผลเสมือนที่ไม่ได้เป็นเจ้าของ เนื่องด้วยข้อกังวลด้านความปลอดภัยที่ว่าแอปที่เป็นอันตรายอาจสร้างจอแสดงผลเสมือนจริงที่เปิดใช้การรองรับการตกแต่งระบบและอ่านข้อมูลที่ละเอียดอ่อนของผู้ใช้จากจอแสดงผล (เช่น รูปภาพส่วนตัว)
การใช้งาน
ใน Android 10 อินเทอร์เฟซ IWallpaperConnection#attachEngine()
และ IWallpaperService#attach()
จะยอมรับพารามิเตอร์ displayId
เพื่อสร้างการเชื่อมต่อต่อจอแสดงผล
WallpaperManagerService.DisplayConnector
บรรจุเครื่องยนต์และการเชื่อมต่อวอลเปเปอร์ต่อจอแสดงผล ใน WindowManager ระบบจะสร้างตัวควบคุมวอลเปเปอร์สำหรับออบเจ็กต์ DisplayContent
แต่ละรายการเมื่อสร้าง แทนที่จะสร้าง WallpaperController
รายการเดียวสำหรับจอแสดงผลทั้งหมด
การใช้งานเมธอด WallpaperManager
สาธารณะบางรายการ (เช่น WallpaperManager#getDesiredMinimumWidth()
) ได้รับการอัปเดตให้คํานวณและให้ข้อมูลสําหรับการแสดงผลที่เกี่ยวข้อง
WallpaperInfo#supportsMultipleDisplays()
และเพิ่มแอตทริบิวต์ทรัพยากรที่เกี่ยวข้องเพื่อให้นักพัฒนาแอปรายงานได้ว่าวอลเปเปอร์ใดพร้อมใช้งานสำหรับหน้าจอหลายขนาด
หากบริการวอลเปเปอร์ที่แสดงบนจอแสดงผลเริ่มต้นไม่รองรับจอแสดงผลหลายจอ ระบบจะแสดงวอลเปเปอร์เริ่มต้นบนจอแสดงผลรอง
รูปที่ 3 ตรรกะสำรองของวอลเปเปอร์สำหรับจอแสดงผลรอง