ข้อมูลอัปเดตเกี่ยวกับพื้นที่เฉพาะของการแสดงผลเหล่านี้จะแสดงอยู่ในหน้านี้
การตกแต่งระบบ
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 ของระบบที่รองรับหลายจอภาพ (MD) ควรจัดการกรณีต่อไปนี้
- การเริ่มต้นระบบจอแสดงผลหลายจอเมื่อเริ่มต้น
- การแสดงผลที่เพิ่มเมื่อรันไทม์
- การแสดงผลถูกนําออกเมื่อรันไทม์
เมื่อ UI ของระบบตรวจพบการเพิ่มจอแสดงผลก่อน WindowManager ก็จะทำให้เกิดการแข่งขัน คุณหลีกเลี่ยงปัญหานี้ได้โดยใช้การเรียกกลับที่กําหนดเองจาก WindowManager ไปยัง UI ของระบบเมื่อเพิ่มจอแสดงผลแทนการสมัครรับเหตุการณ์ DisplayManager.DisplayListener
ดูการใช้งานอ้างอิงสำหรับการสนับสนุนแถบนำทางได้ที่ CommandQueue.Callbacks#onDisplayAddSystemDecorations
และดูการใช้งานอ้างอิงสำหรับวอลเปเปอร์ได้ที่ WallpaperManagerInternal#onDisplayAddSystemDecorations
นอกจากนี้ Android 10 ยังมีอัปเดตต่อไปนี้
- คลาส
NavigationBarController
จะควบคุมฟังก์ชันการทำงานทั้งหมดสำหรับแถบนําทางโดยเฉพาะ - หากต้องการดูแถบนําทางที่กําหนดเอง โปรดดู
CarStatusBar
TYPE_NAVIGATION_BAR
ไม่ได้จํากัดไว้ที่อินสแตนซ์เดียวอีกต่อไปและสามารถใช้ต่อจอแสดงผลได้IWindowManager#hasNavigationBar()
ได้รับการอัปเดตให้รวมพารามิเตอร์displayId
สำหรับ UI ของระบบเท่านั้น
Launcher
ใน 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()
จะเลือกคอมโพเนนต์และ Intent ที่ต้องการโดยอัตโนมัติโดยขึ้นอยู่กับจอแสดงผลที่เปิดหน้าจอหลัก RootActivityContainer#resolveSecondaryHomeActivity()
มีตรรกะในการค้นหาคอมโพเนนต์กิจกรรมของ Launcher โดยขึ้นอยู่กับ Launcher ที่เลือกอยู่ในปัจจุบัน และใช้ค่าเริ่มต้นของระบบได้หากจำเป็น (ดูActivityTaskManagerService#getSecondaryHomeIntent()
)
ข้อจำกัดด้านความปลอดภัย
นอกเหนือจากข้อจำกัดที่มีผลกับกิจกรรมบนจอแสดงผลรองแล้ว โปรแกรมเปิดแอปจะปรากฏเฉพาะในจอแสดงผลเสมือนที่ระบบเป็นเจ้าของเท่านั้น เพื่อหลีกเลี่ยงไม่ให้แอปที่เป็นอันตรายสร้างจอแสดงผลเสมือนที่เปิดใช้การตกแต่งระบบและอ่านข้อมูลที่ละเอียดอ่อนของผู้ใช้จากแพลตฟอร์ม โปรแกรมเปิดไม่แสดงเนื้อหาบนจอแสดงผลเสมือนจริงที่ไม่ใช่ของระบบ
วอลเปเปอร์
ใน Android 10 ขึ้นไป จอแสดงผลรองจะรองรับวอลเปเปอร์ในกรณีต่อไปนี้
รูปที่ 2 วอลเปเปอร์เคลื่อนไหวบนจอแสดงผลภายใน (ด้านบน) และภายนอก (ด้านล่าง)
นักพัฒนาแอปสามารถประกาศการรองรับฟีเจอร์วอลเปเปอร์ได้โดยระบุ
android:supportsMultipleDisplays="true"
ในคำจำกัดความ XML ของ
WallpaperInfo
นอกจากนี้ นักพัฒนาวอลเปเปอร์ยังควรโหลดชิ้นงานโดยใช้บริบทการแสดงผลใน WallpaperService.Engine#getDisplayContext()
ด้วย
เฟรมเวิร์กจะสร้างWallpaperService.Engine
อินสแตนซ์ 1 รายการต่อการแสดงผล 1 ครั้ง เพื่อให้แต่ละเครื่องมือมีแพลตฟอร์มและบริบทการแสดงผลของตนเอง นักพัฒนาแอปต้องตรวจสอบว่าแต่ละเอนจิ้นวาดภาพได้แบบอิสระด้วยอัตราเฟรมที่แตกต่างกันโดยคำนึงถึง VSync
เลือกวอลเปเปอร์สำหรับแต่ละหน้าจอ
Android 10 ไม่รองรับแพลตฟอร์มโดยตรงสำหรับการเลือกวอลเปเปอร์สำหรับแต่ละหน้าจอ ในการดําเนินการนี้ คุณต้องใช้ตัวระบุการแสดงผลที่เสถียรเพื่อคงการตั้งค่าวอลเปเปอร์ไว้ในแต่ละจอแสดงผล
Display#getDisplayId()
เป็นค่าแบบไดนามิก จึงไม่มีการรับประกันว่าจอแสดงผลจริงจะมีรหัสเดียวกันหลังจากรีบูต
อย่างไรก็ตาม Android 10 ได้เพิ่ม DisplayInfo.mAddress
ซึ่งมีตัวระบุที่เสถียรสำหรับจอแสดงผลจริงและสามารถใช้เพื่อการติดตั้งใช้งานอย่างเต็มรูปแบบในอนาคต ขออภัย เราใช้ตรรกะนี้กับ Android 10 ไม่ทันแล้ว โซลูชันที่แนะนำ
- ใช้คลาส
WallpaperManager
เพื่อตั้งค่าวอลเปเปอร์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 ตรรกะสำรองของวอลเปเปอร์สำหรับจอแสดงผลรอง