หลายหน้าต่างใน Android N: สิ่งที่นักพัฒนาจำเป็นต้องรู้เพื่อใช้ให้เกิดประโยชน์สูงสุด

เราให้ภาพรวมว่าการรองรับหลายหน้าต่างที่กำลังจะมีขึ้นใน Android N มีความหมายอย่างไรต่อนักพัฒนา และวิธีใช้ให้เกิดประโยชน์สูงสุด!

การรองรับหลายหน้าต่างเป็นคุณสมบัติที่ดีที่เรากำลังรออยู่ใน Android N และ สิ่งที่เราต้องการให้พร้อมใช้งานบนอุปกรณ์ทั้งหมดมาเป็นเวลานาน. เพื่อให้เป็นประสบการณ์ที่สนุกสนาน นักพัฒนาอาจต้องทำการเปลี่ยนแปลงบางอย่างในแอปเพื่อรองรับอย่างถูกต้อง

หนึ่งในเซสชัน Google I/O มีไว้สำหรับนักพัฒนาเพื่อเรียนรู้เกี่ยวกับ API ใหม่และการเปลี่ยนแปลงพฤติกรรมของระบบที่สนับสนุนหลายหน้าต่าง

เซสชั่นนี้นำเสนอโดย Wale Ogunwale ผู้จัดการฝ่ายเทคนิคของ Android ActivityManager และ ส่วนประกอบเฟรมเวิร์ก WindowManager เขาและทีมเป็นผู้รับผิดชอบการทำงานหลายหน้าต่างบน Android

คุณสามารถชม เซสชันโหมดหลายหน้าต่างบน YouTubeแต่เรายังให้ภาพรวมของเซสชันที่นี่ด้วย

N แนะนำโหมดหลายหน้าต่างที่แตกต่างกันสามโหมด:
  • โหมดแยกหน้าจอ: นี่คือโหมดที่ใช้งานได้ตามค่าเริ่มต้น ตามชื่อที่บอกเป็นนัย ช่วยให้คุณสามารถเปิดแอปพลิเคชันสองรายการเคียงข้างกันได้
  • โหมดอิสระ: ผู้ผลิตสามารถเปิดใช้งานสิ่งนี้บนอุปกรณ์ขนาดใหญ่ ซึ่งช่วยให้ผู้ใช้สามารถปรับขนาดกิจกรรมได้อย่างอิสระ นอกเหนือจากโหมดแบ่งหน้าจอ
  • โหมดภาพซ้อนภาพ: มุ่งเป้าไปที่อุปกรณ์ Android TV โหมดนี้มีไว้สำหรับให้เครื่องเล่นวิดีโอทำงานในหน้าต่างที่ปักหมุดไว้ในขณะที่ผู้ใช้โต้ตอบกับแอปพลิเคชันอื่น
โหมดแยกหน้าจอ Android Nโหมด Android N PiP
มันน่าสังเกตว่า เราได้พูดถึงหลายหน้าต่างบน N มาก่อนและเสนอคำวิจารณ์เกี่ยวกับระบบปัจจุบัน. ด้วยเหตุนี้ เราหวังว่าโหมดอิสระจะเข้าใกล้โหมดภาพซ้อนภาพมากขึ้นอีกเล็กน้อย เนื่องจากจะมีแอปพลิเคชันที่มีประโยชน์ในทุกอุปกรณ์
การเปิดใช้งานการสนับสนุนหลายหน้าต่างในแอปของคุณนั้นง่ายดาย คุณไม่จำเป็นต้องดำเนินการใดๆ หากคุณกำหนดเป้าหมายไปที่ N อยู่แล้ว หากคุณเลือกที่จะปิดใช้งานหลายหน้าต่าง คุณสามารถทำได้โดยตั้งค่า android: resizeableActivity คุณลักษณะกิจกรรมในรายการของคุณไปที่ false. สิ่งนี้ควรทำก็ต่อเมื่อมีเหตุผลสมควรเท่านั้น เนื่องจากจะทำให้แอปของคุณโดดเด่นในทางที่ไม่ดีอยู่เสมอ เปิดตัวในโหมดเต็มหน้าจอแม้ว่าผู้ใช้ (หรือแอปอื่น) จะพยายามเปิดใช้งานในหลายหน้าต่างก็ตาม โหมด. สิ่งสำคัญคือต้องทราบว่าแอตทริบิวต์ของกิจกรรมรูทจะนำไปใช้กับกิจกรรมทั้งหมดภายในสแต็กงาน กล่าวอีกนัยหนึ่ง หากคุณมีกิจกรรมที่แอปอื่นสามารถเริ่มได้ ตรวจสอบให้แน่ใจว่ากิจกรรมนั้นรองรับโหมดหลายหน้าต่าง เนื่องจากคุณไม่สามารถรับประกันได้ว่าแอปอื่นจะเปิดตัวกิจกรรมของคุณในงานใหม่โดยใช้ Intent#FLAG_ACTIVITY_NEW_TASK. ต้องประกาศการสนับสนุนโหมดภาพซ้อนภาพอย่างชัดเจนผ่านทาง android: supportsPictureInPicture คุณลักษณะ. โปรดทราบว่าแอตทริบิวต์นี้จะถูกละเว้นหาก android: resizeableActivity เป็น. false แอตทริบิวต์ .Layout สามารถใช้เพื่อกำหนดขนาดและตำแหน่งเริ่มต้นสำหรับหน้าต่างรูปแบบอิสระ หรือเพื่อระบุความกว้างหรือความสูงขั้นต่ำทั้งสำหรับโหมดรูปแบบอิสระและโหมดแยกหน้าจอ:
  • android: defaultWidth/android: defaultHeight: ขนาดเริ่มต้นของกิจกรรม (โหมดอิสระ)
  • android: gravity: ตำแหน่งเริ่มต้นของกิจกรรม (โหมดอิสระ)
  • android: minimalWidth/android: minimalHeight: ขนาดที่น้อยที่สุดของกิจกรรม (โหมดอิสระและโหมดแยกหน้าจอ)
คุณสามารถค้นหาตัวอย่างโค้ดได้ใน แอปตัวอย่าง Multi-Window Playground ของ Google บน GitHub: AndroidManifest.xml.
ด้วยการแนะนำการรองรับหลายหน้าต่าง คุณอาจต้องตรวจสอบบางสิ่งในแอปของคุณอีกครั้งเพื่อให้แน่ใจว่าทำงานได้อย่างถูกต้อง

ทำความเข้าใจวงจรชีวิตของกิจกรรม

. วงจรชีวิตของกิจกรรม ไม่มีการเปลี่ยนแปลงในโหมดหลายหน้าต่าง: วงจรการใช้งานพื้นฐานของกิจกรรม Android ดังที่ได้กล่าวไปแล้ว ความแตกต่างเล็กน้อยระหว่างสถานะของกิจกรรมอาจส่งผลให้เกิดพฤติกรรมที่ไม่ได้ตั้งใจซึ่งปกติแล้วคุณจะไม่สังเกตเห็นก่อน N สิ่งสำคัญคือต้องรู้ว่า Activity#onResume() และ. Activity#onPause() จะถูกเรียกเมื่อแอปของคุณได้รับหรือสูญเสียโฟกัส แต่ไม่จำเป็นต้องมองเห็นได้เมื่อเริ่มหรือหยุด (โปรดจำไว้ว่าอาจมีเพียงแอปเดียวเท่านั้นที่สามารถโฟกัสได้ในช่วงเวลาใดก็ตาม) สำหรับแอปที่อัปเดตเนื้อหาอย่างต่อเนื่อง (เช่น การเล่นวิดีโอ) ตรวจสอบให้แน่ใจว่าได้จัดการการเริ่มต้นและหยุดการอัปเดตเนื้อหาแล้ว Activity#onStart() และ. Activity#onStop() แทน. ไม่ทำเช่นนั้นกับแอปวิดีโอ เช่น จะหมายความว่าการเล่นจะเกิดขึ้นก็ต่อเมื่อแอปได้รับการโฟกัสเท่านั้นซึ่งขัดต่อวัตถุประสงค์ของโหมดหลายหน้าต่าง แอป YouTube อย่างเป็นทางการประสบปัญหาคล้ายกันเมื่อ Android N Developer Preview เปิดตัวครั้งแรก.

การจัดการการเปลี่ยนแปลงรันไทม์

เมื่อแอปเข้าสู่โหมดหลายหน้าต่าง การกำหนดค่าอุปกรณ์บางอย่างจะเปลี่ยนไป คุณสามารถอนุญาตให้กิจกรรมของคุณเริ่มต้นใหม่ได้ (ในกรณีนี้ การเก็บรักษาชิ้นส่วน อาจเป็นความคิดที่ดี หากกิจกรรมของคุณต้องดำเนินการอย่างเข้มข้นเมื่อเริ่มต้นระบบ) หรือเลือกที่จะทำ จัดการการเปลี่ยนแปลงการกำหนดค่าอย่างชัดเจน แทน. การกำหนดค่าอุปกรณ์สี่แบบอาจเปลี่ยนแปลงเมื่อเข้าสู่หรืออยู่ในโหมดหลายหน้าต่าง: screenSize, smallestScreenSize, screenLayout และ. orientation. อ้างถึง. เอกสารสำหรับนักพัฒนา Android สำหรับข้อมูลเพิ่มเติมเกี่ยวกับแอตทริบิวต์แต่ละรายการ แต่โปรดทราบว่า orientation ไม่ได้หมายถึงการวางแนวของอุปกรณ์ในกรณีนี้อีกต่อไป แต่เป็นเพียงการบ่งชี้ว่าความกว้างของกิจกรรมของคุณมากกว่าความสูง (แนวนอน) หรือ ไม่ใช่ (แนวตั้ง) การประกาศว่ากิจกรรมของคุณจะจัดการกับการเปลี่ยนแปลงเหล่านี้สามารถทำได้จากรายการ:
android: name=".MyActivity"android: configChanges="screenSize|smallestScreenSize|screenLayout|orientation"/>
โปรดทราบว่านี่หมายความว่าคุณจะต้องจัดการกับการเปลี่ยนแปลงเหล่านี้จริงๆ Activity#onConfigurationChanged()โดยการอัปเดตมุมมองด้วยตนเองหรือโหลดทรัพยากรบางอย่างซ้ำ

คุณสมบัติที่ปิดใช้งานในโหมดหลายหน้าต่าง

คุณลักษณะของระบบบางอย่างจะไม่ได้รับผลกระทบจากกิจกรรมของคุณขณะอยู่ในโหมดหลายหน้าต่าง:
  • การเปลี่ยนแปลงแถบสถานะและแถบนำทาง เช่น การหรี่แสง/ซ่อนแถบระบบหรือการใช้โหมดพิเศษ จะไม่มีผลใดๆ สิ่งนี้สมเหตุสมผลเนื่องจากกิจกรรมของคุณใช้พื้นที่เพียงบางส่วนของหน้าจอเท่านั้น
  • ที่ android: screenOrientation คุณลักษณะของกิจกรรมจะไม่มีผลในโหมดหลายหน้าต่าง เนื่องจากกิจกรรมของคุณจะสามารถปรับขนาดได้ จึงไม่สมเหตุสมผลที่จะมีการวางแนวที่ตายตัวอีกต่อไป
มีการเพิ่มการเรียกกลับใหม่สำหรับเหตุการณ์แบบหลายหน้าต่าง รวมถึงวิธีการสืบค้นสถานะปัจจุบัน
  • Activity#onMultiWindowModeChanged(boolean inMultiWindow): เรียกว่าเมื่อสถานะกิจกรรมเปลี่ยนจากเต็มหน้าจอเป็นหลายหน้าต่างและในทางกลับกัน
  • Activity#onPictureInPictureModeChanged(boolean inPictureOnPicture): เรียกเมื่อสถานะกิจกรรมเปลี่ยนเป็น/จากโหมด PIP
  • Activity#isInMultiWindowMode()/Activity#isInPictureInPictureMode(): ส่งคืนว่ากิจกรรมอยู่ในโหมดหลายหน้าต่าง / ภาพซ้อนภาพหรือไม่
  • Activity#overlayWithDecorCaption(boolean overlay): สำหรับหน้าต่างรูปแบบอิสระ สามารถใช้วิธีนี้เพื่อสร้างคำบรรยาย (แถบที่ใช้ลากหน้าต่างไปรอบๆ) ซ้อนทับเนื้อหาแทนที่จะกดลง
ป.ล. ยกเว้น. Activity#overlayWithDecorCaption()วิธีการเหล่านี้จัดทำโดย Fragment ระดับ.

การเริ่มกิจกรรมในโหมดหลายหน้าต่าง

  • Activity#enterPictureInPictureMode() สามารถใช้เพื่อใส่กิจกรรมในโหมดภาพซ้อนภาพ โปรดทราบว่ากิจกรรมในโหมด PiP จะไม่ได้รับการแจ้งเตือนเกี่ยวกับเหตุการณ์อินพุต - การใช้งาน MediaSession#setMediaButtonReceiver() หากคุณต้องการจัดการกับเหตุการณ์ดังกล่าว อย่าลืมตรวจสอบเว็บไซต์นักพัฒนา Android หากคุณสนใจ การแสดงภาพซ้อนภาพบน Android N.
  • หากอุปกรณ์อยู่ในโหมดแบ่งหน้าจอ คุณสามารถบอกให้ระบบเปิดกิจกรรมอื่นถัดจากกิจกรรมของคุณได้โดยใช้ Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT ธง. การตั้งค่าสถานะจะไม่มีผลใดๆ หากไม่อยู่ในโหมดแยกหน้าจอ
  • หากอุปกรณ์อยู่ในโหมดอิสระ ActivityOptions#setLaunchBounds() สามารถใช้เพื่อระบุขนาดและตำแหน่งของกิจกรรมใหม่บนหน้าจอ
สำหรับตัวอย่างโค้ด โปรดดูแอปตัวอย่าง Multi-Window Playground: ตัวอย่างกิจกรรมที่อยู่ติดกัน, ตัวอย่างขอบเขตการเปิดตัว.

ลากแล้ววาง

แม้ว่าการรองรับการลากและวางจะมีมาตั้งแต่ Honeycomb แต่ก่อนหน้านี้สามารถทำได้ในกิจกรรมเดียวกันเท่านั้น ตอนนี้. รองรับหลายหน้าต่าง เช่นกัน. ดูเหมือนว่าการดำเนินการนี้จะเป็น ส่วนใหญ่เหมือนเดิมโดยมีการเพิ่มเติมเล็กน้อยสำหรับการลากและวางข้ามกิจกรรม:
  • View#startDragAndDrop()
    • นามแฝงใหม่สำหรับ View#startDrag().
    • หากต้องการเปิดใช้งานการลากและวางข้ามกิจกรรม ให้ส่งแฟล็กใหม่ View#DRAG_FLAG_GLOBAL.
    • หากคุณต้องการให้สิทธิ์ URI แก่กิจกรรมผู้รับ ให้ส่งแฟล็กใหม่ View#DRAG_FLAG_GLOBAL_URI_READ หรือ View#DRAG_FLAG_GLOBAL_URI_WRITEตามความเหมาะสม
  • View#updateDragShadow()
    • แทนที่เงาการลากสำหรับการดำเนินการลากที่กำลังดำเนินการอยู่ สามารถเรียกได้โดยแอปที่เริ่มต้นการดำเนินการลากเท่านั้น
  • View#cancelDragAndDrop()
    • ยกเลิกการดำเนินการลากที่กำลังดำเนินอยู่ สามารถเรียกได้โดยแอปที่เริ่มต้นการดำเนินการลากเท่านั้น
  • การตรวจสอบว่าอุปกรณ์รองรับโหมดอิสระหรือโหมดภาพซ้อนภาพสามารถทำได้ผ่านทาง PackageManager#hasSystemFeature(), โดยใช้ PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT และ PackageManager#FEATURE_FREEFORM_PICTURE_IN_PICTURE ตามลำดับ
  • ที่ android: windowBackground แอ็ตทริบิวต์สามารถใช้เป็นพื้นหลังที่วาดได้ หากกิจกรรมกำลังถูกปรับขนาดและการเรนเดอร์ล้าหลัง ถ้า android: windowBackground ไม่ได้ตั้งค่า android: windowBackgroundFallback ถูกนำมาใช้แทน โปรดดูตัวอย่างแอปตัวอย่าง Multi-Window Playground.
Wale เสนอแนวทางปฏิบัติที่ดีที่สุดเพื่อให้แน่ใจว่าผู้ใช้ของคุณจะได้รับประสบการณ์ที่ดีที่สุด:
  • โหมดการจัดการเปลี่ยนแปลงอย่างหรูหรา:
    • รักษาความสอดคล้องของ UI โดยไม่คำนึงถึงการวางแนว. ไม่มีองค์ประกอบเปลี่ยนตำแหน่งเพื่อให้สามารถเปลี่ยนได้อย่างราบรื่น
    • ขยายความข้างต้นว่า อย่าสลับระหว่างเลย์เอาต์ที่แตกต่างกันมากสำหรับเลย์เอาต์ของโทรศัพท์/แท็บเล็ต. ให้ปรับเค้าโครงแท็บเล็ตให้มีขนาดเล็กลงเพื่อความสอดคล้องกัน
  • ตรวจสอบให้แน่ใจว่ากิจกรรมของคุณปรับให้เหมาะกับขนาดที่เล็ก โดย ตามรูปแบบการออกแบบวัสดุ.
  • ใช้ FLAG_ACTIVITY_LAUNCH_ADJACENT เมื่อมันสมเหตุสมผลที่จะสร้างประสบการณ์ที่สนุกสนานยิ่งขึ้นในโหมดแบ่งหน้าจอ
  • ประกาศความไม่เข้ากันของการปรับขนาดเมื่อมีเหตุผลเท่านั้น. ดังที่เราได้กล่าวไว้ข้างต้น มันทำให้แอปของคุณโดดเด่นในทางที่ไม่ดี
Wale สิ้นสุดเซสชันโดยเสนอแหล่งข้อมูลที่เป็นประโยชน์เพิ่มเติม:
  • เอกสารหลายหน้าต่าง.
  • แนวทางการออกแบบวัสดุสำหรับโหมดแยกหน้าจอ.
  • ตัวอย่างแอปหลายหน้าต่าง.