การอัปเดตที่ทำในส่วนที่เกี่ยวข้องกับโฆษณา Display โดยเฉพาะมีดังนี้
- การปรับขนาดกิจกรรมและจอแสดงผล
- ขนาดจอแสดงผลและสัดส่วนการแสดงผล
- นโยบาย Display
- การตั้งค่าหน้าต่างแสดงผล
- ตัวระบุ Display แบบคงที่
- การใช้จอแสดงผลมากกว่า 2 จอ
- โฟกัสต่อจอแสดงผล
ปรับขนาดกิจกรรมและจอแสดงผล
หากต้องการระบุว่าแอปอาจไม่รองรับโหมดหลายหน้าต่างหรือการปรับขนาด
กิจกรรมจะใช้แอตทริบิวต์ resizeableActivity=false
ปัญหาทั่วไปที่แอปพบเมื่อมีการปรับขนาดกิจกรรม ได้แก่
- กิจกรรมอาจมีการกำหนดค่าที่แตกต่างจากแอปหรือคอมโพเนนต์อื่นๆ ที่ไม่ใช่ภาพ ข้อผิดพลาดที่พบบ่อยคือการอ่านเมตริกการแสดงผลจากบริบทของแอป ค่าที่แสดงจะไม่ได้รับการปรับให้เข้ากับเมตริกพื้นที่ที่มองเห็นได้ซึ่งกิจกรรมแสดงอยู่
- กิจกรรมอาจไม่จัดการการปรับขนาดและเกิดข้อขัดข้อง แสดง UI ที่บิดเบี้ยว หรือสูญเสียสถานะเนื่องจากการเปิดตัวอีกครั้งโดยไม่ได้บันทึกสถานะอินสแตนซ์
- แอปอาจพยายามใช้พิกัดอินพุตแบบสัมบูรณ์ (แทนพิกัดที่สัมพันธ์กับตำแหน่งหน้าต่าง) ซึ่งอาจทําให้อินพุตในโหมดหลายหน้าต่างใช้งานไม่ได้
ใน Android 7 (และสูงกว่า) คุณสามารถตั้งค่าแอป
resizeableActivity=false
ให้ทำงานในโหมดเต็มหน้าจอเสมอได้ ใน
กรณีนี้ แพลตฟอร์มจะป้องกันไม่ให้กิจกรรมที่ปรับขนาดไม่ได้เข้าสู่โหมดแยก
หน้าจอ หากผู้ใช้พยายามเรียกใช้กิจกรรมที่ปรับขนาดไม่ได้จาก Launcher ขณะที่อยู่ในโหมดแยกหน้าจออยู่แล้ว แพลตฟอร์มจะออกจากโหมดแยกหน้าจอและเปิดใช้กิจกรรมที่ปรับขนาดไม่ได้ในโหมดเต็มหน้าจอ
แอปที่ตั้งค่าแอตทริบิวต์นี้เป็น false
อย่างชัดแจ้งในไฟล์ Manifest ต้องไม่เปิดใช้ในโหมดหลายหน้าต่าง เว้นแต่จะใช้โหมดความเข้ากันได้
- ระบบจะใช้การกำหนดค่าเดียวกันกับกระบวนการ ซึ่งประกอบด้วยกิจกรรมทั้งหมด และคอมโพเนนต์ที่ไม่ใช่กิจกรรม
- การกำหนดค่าที่ใช้เป็นไปตามข้อกำหนด CDD สำหรับจอแสดงผลที่ใช้ได้กับแอป
ใน Android 10 แพลตฟอร์มยังคงป้องกันไม่ให้ กิจกรรมที่ปรับขนาดไม่ได้เข้าสู่โหมดแยกหน้าจอ แต่จะ ปรับขนาดชั่วคราวได้หากกิจกรรมประกาศการวางแนวหรือสัดส่วน ภาพคงที่ หากไม่ได้ระบุไว้ กิจกรรมจะปรับขนาดให้เต็มหน้าจอทั้งหมดเหมือนใน Android 9 และต่ำกว่า
การติดตั้งใช้งานเริ่มต้นจะใช้นโยบายต่อไปนี้
เมื่อมีการประกาศกิจกรรมว่าไม่รองรับการทำงานแบบหลายหน้าต่างผ่านการใช้แอตทริบิวต์ android:resizeableActivity
และเมื่อกิจกรรมนั้นเป็นไปตามเงื่อนไขข้อใดข้อหนึ่งที่อธิบายไว้ด้านล่าง เมื่อการกำหนดค่าหน้าจอที่ใช้ต้องเปลี่ยนแปลง ระบบจะบันทึกกิจกรรมและกระบวนการด้วยการกำหนดค่าเดิม และผู้ใช้จะได้รับความสามารถในการเปิดกระบวนการของแอปอีกครั้งเพื่อใช้การกำหนดค่าหน้าจอที่อัปเดตแล้ว
- มีการวางแนวคงที่ผ่านการใช้
android:screenOrientation
- แอปมีสัดส่วนภาพสูงสุดหรือต่ำสุดเริ่มต้นโดยกำหนดเป้าหมายเป็น API ระดับ หรือประกาศสัดส่วนภาพอย่างชัดเจน
รูปนี้แสดงกิจกรรมที่ปรับขนาดไม่ได้ซึ่งมีสัดส่วนที่ประกาศไว้ เมื่อพับอุปกรณ์ หน้าต่างจะได้รับการปรับขนาดให้พอดีกับพื้นที่โดย คงสัดส่วนภาพเดิมไว้โดยใช้แถบดำด้านบนและด้านล่างที่เหมาะสม นอกจากนี้ เรายังมี ตัวเลือกกิจกรรมการรีสตาร์ทให้แก่ผู้ใช้ทุกครั้งที่มีการเปลี่ยนแปลงพื้นที่แสดงผล ของกิจกรรม
เมื่อกางอุปกรณ์ออก การกำหนดค่า ขนาด และสัดส่วนภาพของ กิจกรรมจะไม่เปลี่ยนแปลง แต่จะแสดงตัวเลือกในการรีสตาร์ทกิจกรรม
เมื่อไม่ได้ตั้งค่า resizeableActivity
(หรือตั้งค่าเป็น
true
) แอปจะรองรับการปรับขนาดอย่างเต็มที่
การใช้งาน
กิจกรรมที่ปรับขนาดไม่ได้ซึ่งมีแนวตั้งหรือสัดส่วนภาพคงที่เรียกว่า
โหมดความเข้ากันได้ของขนาด (SCM) ในโค้ด เงื่อนไขกำหนดไว้ใน
ActivityRecord#shouldUseSizeCompatMode()
เมื่อเปิดใช้กิจกรรม SCM การกำหนดค่าที่เกี่ยวข้องกับหน้าจอ (เช่น ขนาดหรือความหนาแน่น) จะได้รับการแก้ไข
ในการกำหนดค่าการลบล้างที่ขอ ดังนั้นกิจกรรมจึงไม่ขึ้นอยู่กับการกำหนดค่าการแสดงผลปัจจุบันอีกต่อไป
หากกิจกรรม SCM ไม่สามารถแสดงเต็มหน้าจอได้ ระบบจะจัดกิจกรรมไว้ที่ด้านบนและ
กึ่งกลางในแนวนอน ขอบเขตกิจกรรมคำนวณโดย
AppWindowToken#calculateCompatBoundsTransformation()
เมื่อกิจกรรม SCM ใช้การกำหนดค่าหน้าจอที่แตกต่างจากคอนเทนเนอร์ (เช่น มีการปรับขนาดจอแสดงผล หรือย้ายกิจกรรมไปยังจอแสดงผลอื่น
) ActivityRecord#inSizeCompatMode()
จะเป็นจริงและ
SizeCompatModeActivityController
(ใน UI ของระบบ) จะได้รับการ
เรียกกลับเพื่อแสดงปุ่มรีสตาร์ทกระบวนการ
ขนาดการแสดงผลและสัดส่วนการแสดงผล
Android 10 รองรับสัดส่วนภาพใหม่
ตั้งแต่สัดส่วนสูงของหน้าจอแบบยาวและบางไปจนถึงสัดส่วน 1:1 แอปสามารถกำหนด
ApplicationInfo#maxAspectRatio
และApplicationInfo#minAspectRatio
ของหน้าจอที่แอป
จัดการได้
รูปที่ 1 ตัวอย่างสัดส่วนแอปที่รองรับใน Android 10
การติดตั้งใช้งานอุปกรณ์อาจมีจอแสดงผลรองที่มีขนาดและความละเอียดเล็กกว่าที่ Android 9 กำหนด และต่ำกว่า (ความกว้างหรือความสูงขั้นต่ำ 2.5 นิ้ว ความละเอียดขั้นต่ำ 320 DP สำหรับ smallestScreenWidth
)
แต่จะวางได้เฉพาะกิจกรรมที่เลือกใช้เพื่อรองรับจอแสดงผลขนาดเล็กเหล่านี้เท่านั้น
แอปสามารถเลือกใช้ได้โดยการประกาศขนาดขั้นต่ำที่รองรับซึ่งเล็กกว่า
หรือเท่ากับขนาดการแสดงผลเป้าหมาย โดยใช้แอตทริบิวต์เลย์เอาต์กิจกรรม android:minHeight
และ
android:minWidth
ใน
AndroidManifest
นโยบายการแสดงผล
Android 10 จะแยกและย้ายนโยบายการแสดงผลบางอย่าง
จากWindowManagerPolicy
การใช้งานเริ่มต้นใน
PhoneWindowManager
ไปยังคลาสต่อการแสดงผล เช่น
- สถานะและการหมุนจอแสดงผล
- การติดตามเหตุการณ์การเคลื่อนไหวและคีย์บางรายการ
- หน้าต่าง UI ของระบบและการตกแต่ง
ใน Android 9 (และต่ำกว่า) คลาส PhoneWindowManager
จะจัดการนโยบายการแสดงผล สถานะและการตั้งค่า การหมุน กรอบหน้าต่างตกแต่ง การติดตาม และอื่นๆ
Android 10 ย้ายข้อมูลส่วนใหญ่ไปที่คลาส DisplayPolicy
ยกเว้นการติดตามการหมุน ซึ่งย้ายไปที่ DisplayRotation
การตั้งค่ากรอบเวลาการแสดงผล
ใน Android 10 การตั้งค่าการแสดงหน้าต่างต่อจอแสดงผลที่กำหนดค่าได้ได้รับการขยายให้รวมถึงรายการต่อไปนี้
- โหมดการแสดงผลแบบหน้าต่างเริ่มต้น
- ค่า Overscan
- การหมุนผู้ใช้และโหมดการหมุน
- โหมดขนาด ความหนาแน่น และการปรับขนาดที่บังคับ
- โหมดการนำเนื้อหาออก (เมื่อนำโฆษณา Display ออก)
- การรองรับการตกแต่งระบบและ IME
คลาส DisplayWindowSettings
มีการตั้งค่าสำหรับตัวเลือกเหล่านี้
ระบบจะบันทึกข้อมูลเหล่านี้ลงในดิสก์ในพาร์ติชัน /data
ใน
display_settings.xml
ทุกครั้งที่มีการเปลี่ยนแปลงการตั้งค่า โปรดดูรายละเอียดที่ DisplayWindowSettings.AtomicFileStorage
และ
DisplayWindowSettings#writeSettings()
ผู้ผลิตอุปกรณ์สามารถ
ระบุค่าเริ่มต้นใน display_settings.xml
สำหรับการกำหนดค่าอุปกรณ์
ของตนได้ อย่างไรก็ตาม เนื่องจากไฟล์จัดเก็บอยู่ใน /data
จึงอาจต้องใช้ตรรกะเพิ่มเติมเพื่อกู้คืนไฟล์หากมีการลบด้วยการล้างข้อมูล
โดยค่าเริ่มต้น Android 10 จะใช้
DisplayInfo#uniqueId
เป็นตัวระบุสำหรับการแสดงผลเมื่อคงการตั้งค่าไว้ uniqueId
ควรระบุสำหรับจอแสดงผลทั้งหมด นอกจากนี้ ยังมีความเสถียรสำหรับจอแสดงผลจริงและจอแสดงผลเครือข่าย นอกจากนี้ คุณยัง
ใช้พอร์ตของจอแสดงผลจริงเป็นตัวระบุได้ด้วย ซึ่งตั้งค่าได้ใน
DisplayWindowSettings#mIdentifier
เมื่อเขียนแต่ละครั้ง ระบบจะเขียนการตั้งค่าทั้งหมด
เพื่อให้คุณอัปเดตคีย์ที่ใช้สำหรับรายการที่แสดงใน
ที่เก็บข้อมูลได้อย่างปลอดภัย โปรดดูรายละเอียดที่ตัวระบุการแสดงผลแบบคงที่
ระบบจะบันทึกการตั้งค่าไว้ในไดเรกทอรี /data
ด้วยเหตุผลทางประวัติศาสตร์
เดิมทีใช้เพื่อคงการตั้งค่าที่ผู้ใช้กำหนด เช่น
การหมุนเวียนโฆษณา
ตัวระบุการแสดงผลแบบคงที่
Android 9 (และต่ำกว่า) ไม่ได้ระบุตัวระบุที่เสถียรสำหรับจอแสดงผลใน
เฟรมเวิร์ก เมื่อเพิ่มจอแสดงผลลงในระบบ ระบบจะสร้าง Display#mDisplayId
หรือ DisplayInfo#displayId
สำหรับจอแสดงผลนั้นโดยการเพิ่มตัวนับแบบคงที่ หากระบบ
เพิ่มและนำจอแสดงผลเดียวกันออก ระบบจะกำหนดรหัสที่แตกต่างกัน
หากอุปกรณ์มีจอแสดงผลหลายจอตั้งแต่ตอนบูต ระบบอาจ
กำหนดตัวระบุที่แตกต่างกันให้กับจอแสดงผลเหล่านั้น ทั้งนี้ขึ้นอยู่กับเวลา แม้ว่า Android 9 (และเวอร์ชันก่อนหน้า) จะมี DisplayInfo#uniqueId
แต่ก็ไม่มีข้อมูลเพียงพอที่จะแยกความแตกต่างระหว่างจอแสดงผล เนื่องจากระบบจะระบุจอแสดงผลจริงเป็น local:0
หรือ local:1
เพื่อแสดงถึงจอแสดงผลในตัวและจอแสดงผลภายนอก
Android 10 เปลี่ยนแปลง DisplayInfo#uniqueId
เพื่อเพิ่มตัวระบุที่เสถียรและเพื่อแยกความแตกต่างระหว่างจอแสดงผลในเครื่อง เครือข่าย และ
เสมือน
ประเภทจอแสดงผล | รูปแบบ |
---|---|
ในพื้นที่ | local:<stable-id> |
เครือข่าย | network:<mac-address> |
เสมือนจริง | virtual:<package-name-and-name> |
นอกเหนือจากการอัปเดต uniqueId
แล้ว
DisplayInfo.address
ยังมี DisplayAddress
ซึ่งเป็น
ตัวระบุจอแสดงผลที่เสถียรเมื่อรีบูต ใน Android
10 DisplayAddress
รองรับจอแสดงผลจริง
และจอแสดงผลเครือข่าย DisplayAddress.Physical
มีรหัสแสดงผลที่เสถียร (เช่นเดียวกับใน uniqueId
) และสร้างได้ด้วย
DisplayAddress#fromPhysicalDisplayId()
Android 10 ยังมีวิธีที่สะดวกในการรับข้อมูลพอร์ต (Physical#getPort()
) อีกด้วย ซึ่งสามารถใช้ในเฟรมเวิร์กเพื่อระบุจอแสดงผลแบบคงที่ได้ ตัวอย่างเช่น ใช้ใน
DisplayWindowSettings
) DisplayAddress.Network
มีที่อยู่ MAC และสร้างได้ด้วย
DisplayAddress#fromMacAddress()
การเพิ่มข้อมูลเหล่านี้ช่วยให้ผู้ผลิตอุปกรณ์ระบุจอแสดงผลในการตั้งค่าแบบหลายจอแสดงผลแบบคงที่
และกำหนดค่าการตั้งค่าและฟีเจอร์ต่างๆ ของระบบ
โดยใช้ตัวระบุจอแสดงผลแบบคงที่ เช่น พอร์ตสำหรับจอแสดงผลจริง ระบบจะซ่อนเมธอดเหล่านี้และมีไว้ให้ใช้ภายใน system_server
เท่านั้น
เมื่อระบุรหัสจอแสดงผล HWC (ซึ่งอาจไม่ชัดเจนและไม่เสถียรเสมอไป) เมธอดนี้จะแสดงหมายเลขพอร์ต 8 บิต (เฉพาะแพลตฟอร์ม) ที่ระบุขั้วต่อจริงสำหรับการแสดงผล รวมถึง Blob EDID ของจอแสดงผล
SurfaceFlinger จะดึงข้อมูลผู้ผลิตหรือรุ่นจาก EDID เพื่อ
สร้างรหัสการแสดงผลแบบ 64 บิตที่เสถียรซึ่งแสดงต่อเฟรมเวิร์ก หากไม่รองรับหรือเกิดข้อผิดพลาดในเมธอดนี้ SurfaceFlinger จะกลับไปใช้โหมด MD เดิม
ซึ่ง DisplayInfo#address
เป็นค่าว่างและ
DisplayInfo#uniqueId
เป็นแบบฮาร์ดโค้ดตามที่อธิบายไว้ข้างต้น
หากต้องการยืนยันว่าระบบรองรับฟีเจอร์นี้ ให้เรียกใช้คำสั่งต่อไปนี้
$ dumpsys SurfaceFlinger --display-id # Example output. Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32" Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i" Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"
ใช้จอแสดงผลมากกว่า 2 จอ
ใน Android 9 (และต่ำกว่า) SurfaceFlinger และ DisplayManagerService
ถือว่ามีจอแสดงผลจริงอย่างมาก 2 จอที่มีรหัส 0
และ 1 ที่ฮาร์ดโค้ด
ตั้งแต่ Android 10 เป็นต้นมา SurfaceFlinger สามารถใช้ประโยชน์จาก API ของ Hardware Composer (HWC) เพื่อสร้างรหัสจอแสดงผลที่เสถียร ซึ่งช่วยให้จัดการจอแสดงผลจริงได้ตามจำนวนที่ต้องการ ดูข้อมูลเพิ่มเติมได้ที่ ตัวระบุแบบคงที่ของโฆษณา Display
เฟรมเวิร์กสามารถค้นหาโทเค็น IBinder
สำหรับจอแสดงผลจริงผ่าน SurfaceControl#getPhysicalDisplayToken
หลังจากได้รับรหัสจอแสดงผลแบบ 64 บิตจาก SurfaceControl#getPhysicalDisplayIds
หรือจากเหตุการณ์ DisplayEventReceiver
ที่เสียบร้อน
ใน Android 10 (และต่ำกว่า) จอแสดงผลภายในหลักคือ TYPE_INTERNAL
และจอแสดงผลรองทั้งหมดจะได้รับการแจ้งว่า TYPE_EXTERNAL
ไม่ว่าจะเป็นการเชื่อมต่อประเภทใดก็ตาม ดังนั้น จอแสดงผลภายในเพิ่มเติมจึงถือเป็นจอแสดงผลภายนอก
วิธีแก้ปัญหาชั่วคราวคือโค้ดเฉพาะอุปกรณ์สามารถคาดการณ์เกี่ยวกับ
DisplayAddress.Physical#getPort
หากทราบ HWC และตรรกะการจัดสรรพอร์ต
สามารถคาดการณ์ได้
ข้อจำกัดนี้จะไม่มีใน Android 11 (และสูงกว่า)
- ใน Android 11 จอแสดงผลแรกที่รายงานระหว่างการบูตคือจอแสดงผลหลัก ประเภทการเชื่อมต่อ (ภายในเทียบกับภายนอก) ไม่เกี่ยวข้อง อย่างไรก็ตาม จอแสดงผลหลักจะยังคงเชื่อมต่ออยู่และต้องเป็นจอแสดงผลภายในในการใช้งานจริง โปรดทราบว่าโทรศัพท์แบบพับได้บางรุ่นมี จอแสดงผลภายในหลายจอ
- ระบบจะจัดหมวดหมู่จอแสดงผลรองอย่างถูกต้องเป็น
Display.TYPE_INTERNAL
หรือDisplay.TYPE_EXTERNAL
(เดิมเรียกว่าDisplay.TYPE_BUILT_IN
และDisplay.TYPE_HDMI
ตามลำดับ) โดยขึ้นอยู่กับประเภทการเชื่อมต่อ
การใช้งาน
ใน Android 9 และต่ำกว่า ระบบจะระบุจอแสดงผลด้วยรหัส 32 บิต
โดยที่ 0 คือจอแสดงผลภายใน 1 คือจอแสดงผลภายนอก [2, INT32_MAX]
คือจอแสดงผลเสมือน HWC และ -1 คือจอแสดงผลที่ไม่ถูกต้องหรือจอแสดงผลเสมือนที่ไม่ใช่ HWC
ตั้งแต่ Android 10 เป็นต้นไป จอแสดงผลจะมีรหัสที่เสถียร
และถาวร ซึ่งช่วยให้ SurfaceFlinger และ DisplayManagerService
ติดตามจอแสดงผลได้มากกว่า 2 จอ และจดจำจอแสดงผลที่เคยเห็นได้ หาก HWC
รองรับ IComposerClient.getDisplayIdentificationData
และให้ข้อมูลการระบุจอแสดงผล
SurfaceFlinger จะแยกวิเคราะห์โครงสร้าง EDID และจัดสรรรหัสจอแสดงผลแบบ 64 บิตที่เสถียร
สำหรับจอแสดงผลจริงและจอแสดงผลเสมือนของ HWC โดยจะแสดงรหัสโดยใช้
ประเภทตัวเลือก ซึ่งค่า Null หมายถึงจอแสดงผลที่ไม่ถูกต้องหรือจอแสดงผลเสมือนที่ไม่ใช่ HWC
หากไม่มีการรองรับ HWC SurfaceFlinger จะกลับไปใช้ลักษณะการทำงานเดิมที่มีจอแสดงผลจริงอย่างน้อย 2 จอ
โฟกัสต่อจอแสดงผล
Android 10 สามารถกำหนดค่าให้รองรับหน้าต่างที่โฟกัสหลายหน้าต่างได้ โดยมีอย่างมาก 1 หน้าต่างต่อจอแสดงผล เพื่อรองรับแหล่งที่มาของอินพุตหลายแหล่งที่กำหนดเป้าหมายไปยังจอแสดงผลแต่ละจอพร้อมกัน การตั้งค่านี้มีไว้สำหรับอุปกรณ์ประเภทพิเศษเท่านั้น เมื่อผู้ใช้หลายคนโต้ตอบกับอุปกรณ์เดียวกันในเวลาเดียวกันและใช้วิธีการหรืออุปกรณ์อินพุตที่แตกต่างกัน เช่น Android Automotive
เราขอแนะนำไม่ให้เปิดใช้ฟีเจอร์นี้ในอุปกรณ์ทั่วไป ซึ่งรวมถึงอุปกรณ์แบบหลายหน้าจอหรืออุปกรณ์ที่ใช้สำหรับประสบการณ์การใช้งานแบบเดสก์ท็อป สาเหตุหลักมาจากข้อกังวลด้านความปลอดภัยที่อาจทำให้ผู้ใช้ สงสัยว่าหน้าต่างใดมีโฟกัสอินพุต
ลองนึกถึงผู้ใช้ที่ป้อนข้อมูลที่ปลอดภัยลงในช่องป้อนข้อความ อาจจะเป็นการเข้าสู่ระบบแอปธนาคารหรือป้อนข้อความที่มีข้อมูลที่ละเอียดอ่อน แอปที่เป็นอันตรายอาจสร้างจอแสดงผลเสมือนนอกหน้าจอเพื่อใช้ในการดำเนินการ รวมถึงมีช่องป้อนข้อความด้วย กิจกรรมที่ถูกต้องและกิจกรรมที่เป็นอันตรายจะได้รับโฟกัส และทั้ง 2 กิจกรรมจะแสดงตัวบ่งชี้การป้อนข้อมูลที่ใช้งานอยู่ (เคอร์เซอร์กะพริบ)
อย่างไรก็ตาม เนื่องจากระบบจะป้อนข้อมูลจากแป้นพิมพ์ (ฮาร์ดแวร์หรือซอฟต์แวร์) ลงใน กิจกรรมที่อยู่บนสุดเท่านั้น (แอปที่เปิดใช้ล่าสุด) การ สร้างจอแสดงผลเสมือนที่ซ่อนอยู่ทำให้แอปที่เป็นอันตรายสามารถดึงข้อมูลที่ผู้ใช้ป้อนได้ แม้ว่า จะใช้แป้นพิมพ์ซอฟต์แวร์บนจอแสดงผลหลักของอุปกรณ์ก็ตาม
ใช้ com.android.internal.R.bool.config_perDisplayFocusEnabled
เพื่อตั้งค่าโฟกัสต่อจอแสดงผล
ความเข้ากันได้
ปัญหา: ใน Android 9 และต่ำกว่า ระบบจะโฟกัสหน้าต่างได้สูงสุด 1 หน้าต่างในแต่ละครั้ง
วิธีแก้ปัญหา: ในกรณีที่เกิดขึ้นไม่บ่อยนักเมื่อหน้าต่าง 2 บานจาก กระบวนการเดียวกันจะได้รับโฟกัส ระบบจะให้โฟกัสเฉพาะหน้าต่าง ที่อยู่สูงกว่าในลำดับ Z ระบบจะยกเลิกข้อจํากัดนี้สําหรับแอปที่กําหนดเป้าหมายเป็น Android 10 ซึ่งคาดว่าแอปจะ รองรับการโฟกัสหลายหน้าต่างพร้อมกันได้
การใช้งาน
WindowManagerService#mPerDisplayFocusEnabled
ควบคุม
ความพร้อมใช้งานของฟีเจอร์นี้ ใน ActivityManager
ActivityDisplay#getFocusedStack()
จะใช้แทนการติดตามทั่วโลก
ในตัวแปร ActivityDisplay#getFocusedStack()
กำหนดโฟกัสตามลำดับ Z แทนที่จะแคชค่า เพื่อให้มีเพียงแหล่งที่มาเดียวคือ WindowManager ที่ต้องติดตามลำดับ Z ของกิจกรรม
ActivityStackSupervisor#getTopDisplayFocusedStack()
ใช้
แนวทางที่คล้ายกันในกรณีที่ต้องระบุสแต็กที่โฟกัสสูงสุดในระบบ
ระบบจะข้ามสแต็กจากบนลงล่างเพื่อค้นหาสแต็กแรกที่มีสิทธิ์
InputDispatcher
ตอนนี้มีหน้าต่างที่โฟกัสได้หลายหน้าต่าง
(หน้าต่างละ 1 จอแสดงผล) หากเหตุการณ์อินพุตเป็นเหตุการณ์เฉพาะจอแสดงผล ระบบจะส่งเหตุการณ์ไปยังหน้าต่างที่โฟกัสในจอแสดงผลที่เกี่ยวข้อง มิเช่นนั้น ระบบจะส่งไปยังหน้าต่างที่โฟกัสในจอแสดงผลที่โฟกัส ซึ่งเป็นจอแสดงผลที่ผู้ใช้โต้ตอบด้วยล่าสุด
โปรดอ่านInputDispatcher::mFocusedWindowHandlesByDisplay
และ
InputDispatcher::setFocusedDisplay()
นอกจากนี้ แอปที่โฟกัสจะได้รับการอัปเดต
แยกกันใน InputManagerService ผ่าน
NativeInputManager::setFocusedApplication()
ด้วย
ใน WindowManager
ระบบจะติดตามหน้าต่างที่โฟกัสแยกกันด้วย
ดูDisplayContent#mCurrentFocus
และ
DisplayContent#mFocusedApp
รวมถึงการใช้งานที่เกี่ยวข้อง เราได้ย้ายวิธีการติดตามและอัปเดตโฟกัสที่เกี่ยวข้องจาก
WindowManagerService
ไปยัง DisplayContent
แล้ว