Tasks และแบ็กสแต็ก

งานคือคอลเล็กชันกิจกรรมที่ผู้ใช้โต้ตอบด้วยเมื่อพยายามทำสิ่งต่างๆ ในแอปของคุณ กิจกรรมเหล่านี้จะจัดเรียงเป็นสแต็กที่เรียกว่า Back Stack ตามลำดับการเปิดแต่ละกิจกรรม

เช่น แอปอีเมลอาจมีกิจกรรมหนึ่งเพื่อแสดงรายการข้อความใหม่ เมื่อผู้ใช้เลือกข้อความ กิจกรรมใหม่จะเปิดขึ้นเพื่อดูข้อความนั้น ระบบจะเพิ่มกิจกรรมใหม่นี้ลงใน Back Stack จากนั้นเมื่อผู้ใช้แตะหรือใช้ท่าทางสัมผัสเพื่อย้อนกลับ กิจกรรมใหม่นั้นจะสิ้นสุดลงและถูกนำออกจากสแต็ก

วงจรของงานและ Back Stack

หน้าจอหลักของอุปกรณ์เป็นจุดเริ่มต้นสำหรับงานส่วนใหญ่ เมื่อผู้ใช้แตะไอคอนของแอปหรือทางลัดในตัวเปิดแอปหรือบนหน้าจอหลัก งานของแอปนั้นจะปรากฏขึ้นที่เบื้องหน้า หากไม่มีงานสำหรับแอป ระบบจะสร้างงานใหม่และกิจกรรมหลักสำหรับแอปนั้นจะเปิดขึ้นเป็นกิจกรรมรูทในสแต็ก

เมื่อกิจกรรมปัจจุบันเริ่มกิจกรรมอื่น ระบบจะพุชกิจกรรมใหม่ไปที่ด้านบนของสแต็กและโฟกัสที่กิจกรรมนั้น กิจกรรมก่อนหน้าจะยังคงอยู่ในสแต็ก แต่จะหยุดทำงาน เมื่อกิจกรรมหยุดลง ระบบจะคงสถานะปัจจุบันของอินเทอร์เฟซผู้ใช้ไว้ เมื่อผู้ใช้ดำเนินการย้อนกลับ ระบบจะนำกิจกรรมปัจจุบันออกจากด้านบนของสแต็กและทำลายกิจกรรมนั้น กิจกรรมก่อนหน้าจะกลับมาทำงานต่อ และระบบจะกู้คืนสถานะก่อนหน้าของ UI

กิจกรรมในสแต็กจะไม่ได้รับการจัดเรียงใหม่ แต่จะพุชเมื่อเริ่มต้นและป๊อปเมื่อปิดด้วยปุ่มย้อนกลับหรือท่าทางสัมผัส ดังนั้น Back Stack จึงทำงานเป็นโครงสร้างแบบเข้าทีหลังออกก่อน ดังที่แสดงในรูปที่ 1

รูปที่ 1 ภาพแสดงวิธีที่กิจกรรมใหม่แต่ละรายการในงานเพิ่มรายการลงใน Back Stack เมื่อผู้ใช้แตะหรือใช้ท่าทางสัมผัสเพื่อย้อนกลับ ระบบจะทำลายกิจกรรมปัจจุบันและกลับมาทำกิจกรรมก่อนหน้าต่อ

เมื่อผู้ใช้แตะหรือใช้ท่าทางสัมผัสเพื่อย้อนกลับต่อไป กิจกรรมแต่ละรายการในสแต็กจะถูกนำออกเพื่อแสดงกิจกรรมก่อนหน้า จนกว่าผู้ใช้จะกลับไปที่หน้าจอหลักหรือกิจกรรมที่ทำงานอยู่เมื่อเริ่มงาน เมื่อนำกิจกรรมทั้งหมดออกจากกลุ่มแล้ว งานจะไม่มีอยู่อีกต่อไป

ลักษณะการทำงานของการแตะด้านหลังสำหรับกิจกรรม Launcher ระดับรูท

กิจกรรม Launcher ระดับรูทคือกิจกรรมที่ประกาศตัวกรอง Intent ที่มีทั้ง ACTION_MAIN และ CATEGORY_LAUNCHER กิจกรรมเหล่านี้มีความโดดเด่นเนื่องจากทำหน้าที่เป็นจุดแรกเข้าสู่แอปของคุณจากตัวเปิดแอปและใช้เพื่อเริ่มงาน

เมื่อผู้ใช้แตะหรือใช้ท่าทางสัมผัสเพื่อย้อนกลับจากกิจกรรม Launcher ระดับรูท ระบบจะจัดการเหตุการณ์แตกต่างกันไปตามเวอร์ชัน Android ที่อุปกรณ์ใช้อยู่

ลักษณะการทำงานของระบบใน Android 11 และต่ำกว่า
ระบบจะสิ้นสุดกิจกรรม
ลักษณะการทำงานของระบบใน Android 12 ขึ้นไป

ระบบจะย้ายกิจกรรมและงานของกิจกรรมไปที่เบื้องหลังแทนที่จะทำให้กิจกรรมเสร็จสิ้น ลักษณะการทำงานนี้ตรงกับลักษณะการทำงานเริ่มต้นของระบบเมื่อออกจากแอปโดยใช้ปุ่มหน้าแรกหรือท่าทางสัมผัส

ในกรณีส่วนใหญ่ ลักษณะการทำงานนี้หมายความว่าผู้ใช้จะกลับมาใช้แอปของคุณต่อได้อย่างรวดเร็วจากสถานะอุ่น แทนที่จะต้องรีสตาร์ทแอปใหม่ทั้งหมดจากสถานะเย็น

หากต้องการใช้การนำทางย้อนกลับที่กำหนดเอง เราขอแนะนำให้ใช้ AndroidX Activity API แทนการลบล้าง onBackPressed() AndroidX Activity API จะเลื่อนไปใช้ลักษณะการทำงานของระบบที่เหมาะสมโดยอัตโนมัติหากไม่มีคอมโพเนนต์ที่ขัดจังหวะการแตะปุ่มย้อนกลับของระบบ

อย่างไรก็ตาม หากแอปของคุณลบล้าง onBackPressed() เพื่อจัดการการนำทางย้อนกลับและสิ้นสุดกิจกรรม ให้อัปเดตการติดตั้งใช้งานเพื่อเรียกใช้ super.onBackPressed() แทนการสิ้นสุด การเรียกใช้ super.onBackPressed() จะย้ายกิจกรรมและงานไปยังเบื้องหลังเมื่อเหมาะสม และมอบประสบการณ์การนําทางที่สอดคล้องกันมากขึ้นสําหรับผู้ใช้ในแอปต่างๆ

งานที่ทำงานอยู่เบื้องหลังและเบื้องหน้า

รูปที่ 2 งาน 2 อย่าง: งาน B ได้รับการโต้ตอบจากผู้ใช้ในเบื้องหน้า ขณะที่งาน A อยู่ในเบื้องหลังเพื่อรอให้กลับมาทำงานต่อ

งานคือหน่วยที่เชื่อมโยงกันซึ่งสามารถย้ายไปที่เบื้องหลังเมื่อผู้ใช้เริ่มงานใหม่หรือไปที่หน้าจอหลัก ขณะอยู่ในเบื้องหลัง กิจกรรมทั้งหมดในงานจะหยุดลง แต่ Back Stack ของงานจะยังคงอยู่เหมือนเดิม โดยงานจะสูญเสียโฟกัสขณะที่งานอื่นเกิดขึ้น ดังที่แสดงในรูปที่ 2 จากนั้นงานจะกลับมาทำงานในเบื้องหน้าเพื่อให้ผู้ใช้กลับมาทำงานต่อจากที่ค้างไว้ได้

พิจารณาโฟลว์งานต่อไปนี้สำหรับงาน A ปัจจุบันที่มีกิจกรรม 3 รายการในสแต็ก ซึ่งรวมถึง 2 รายการภายใต้กิจกรรมปัจจุบัน

  1. ผู้ใช้ใช้ปุ่มหน้าแรกหรือท่าทางสัมผัส จากนั้นเริ่มแอปใหม่จากตัวเปิดแอป

    เมื่อหน้าจอหลักปรากฏขึ้น งาน A จะไปทำงานอยู่เบื้องหลัง เมื่อแอปใหม่เริ่มทำงาน ระบบจะเริ่มงานสำหรับแอปนั้น (งาน B) โดยมีสแต็กกิจกรรมของตัวเอง

  2. หลังจากโต้ตอบกับแอปนั้นแล้ว ผู้ใช้จะกลับไปที่หน้าแรกอีกครั้งและเลือกแอปที่เริ่มงาน A ในตอนแรก

    ตอนนี้งาน A จะมาอยู่เบื้องหน้า โดยกิจกรรมทั้ง 3 รายการในสแต็กจะยังคงอยู่ และกิจกรรมที่ด้านบนของสแต็กจะกลับมาทำงานอีกครั้ง ณ จุดนี้ ผู้ใช้ยังสามารถเปลี่ยนกลับไปที่งาน B ได้โดยไปที่หน้าแรกและเลือกไอคอนแอปที่เริ่มงานนั้น หรือโดยการเลือกงานของแอปจากหน้าจอล่าสุด

อินสแตนซ์กิจกรรมหลายรายการ

รูปที่ 3 กิจกรรมเดียวสามารถสร้างอินสแตนซ์ได้หลายครั้ง

เนื่องจากกิจกรรมใน Back Stack ไม่เคยมีการจัดเรียงใหม่ หากแอปของคุณอนุญาตให้ผู้ใช้เริ่มกิจกรรมหนึ่งๆ จากกิจกรรมมากกว่า 1 รายการ ระบบจะสร้างอินสแตนซ์ใหม่ของกิจกรรมนั้นและพุชไปยังสแต็ก แทนที่จะนำอินสแตนซ์ก่อนหน้าของกิจกรรมนั้นมาไว้ด้านบนสุด ด้วยเหตุนี้ กิจกรรมหนึ่งในแอปของคุณอาจสร้างอินสแตนซ์หลายครั้ง แม้จะมาจากงานที่ต่างกัน ดังที่แสดงในรูปที่ 3

หากผู้ใช้ย้อนกลับโดยใช้ปุ่มย้อนกลับหรือท่าทางสัมผัส อินสแตนซ์ของกิจกรรมจะแสดงตามลำดับที่เปิด โดยแต่ละอินสแตนซ์จะมีสถานะ UI ของตัวเอง อย่างไรก็ตาม คุณสามารถแก้ไขลักษณะการทำงานนี้ได้หากไม่ต้องการให้สร้างอินสแตนซ์กิจกรรมมากกว่า 1 ครั้ง ดูข้อมูลเพิ่มเติมได้ที่หัวข้อจัดการงาน

สภาพแวดล้อมแบบหลายหน้าต่าง

เมื่อแอปทำงานพร้อมกันในสภาพแวดล้อมแบบหลายหน้าต่าง ซึ่งรองรับใน Android 7.0 (ระดับ API 24) ขึ้นไป ระบบจะจัดการงานแยกกันสำหรับแต่ละหน้าต่าง แต่ละหน้าต่างมีงานได้หลายรายการ เช่นเดียวกับแอป Android ที่ทำงานบน Chromebook ระบบจะจัดการงานหรือกลุ่มงานตามหน้าต่าง

สรุปวงจรชีวิต

สรุปลักษณะการทำงานเริ่มต้นสำหรับกิจกรรมและงานต่างๆ ได้ดังนี้

  • เมื่อกิจกรรม A เริ่มกิจกรรม B กิจกรรม A จะหยุดลง แต่ระบบจะคงสถานะไว้ เช่น ตำแหน่งการเลื่อนและข้อความที่ป้อนลงในแบบฟอร์ม หากผู้ใช้แตะหรือใช้ท่าทางสัมผัส "กลับ" ขณะอยู่ในกิจกรรม B กิจกรรม A จะกลับมาทำงานอีกครั้งโดยคืนค่าสถานะเดิม

  • เมื่อผู้ใช้ออกจากงานโดยใช้ปุ่มหน้าแรกหรือท่าทางสัมผัส กิจกรรมปัจจุบันจะหยุดลงและงานจะไปอยู่ในเบื้องหลัง ระบบจะคงสถานะของทุกกิจกรรมในงานไว้ หากผู้ใช้กลับมาทำงานต่อในภายหลังโดยเลือกไอคอน Launcher ที่เริ่มงาน งานจะกลับมาทำงานในเบื้องหน้าและกลับมาทำกิจกรรมที่ด้านบนของสแต็กต่อ

  • หากผู้ใช้แตะหรือใช้ท่าทางสัมผัสเพื่อย้อนกลับ ระบบจะนำกิจกรรมปัจจุบันออกจากสแต็กและทำลายทิ้ง กิจกรรมก่อนหน้าในสแต็กจะกลับมาทำงานต่อ เมื่อกิจกรรมถูกทำลาย ระบบจะไม่เก็บสถานะของกิจกรรมไว้

    ลักษณะการทำงานนี้จะแตกต่างออกไปสำหรับกิจกรรม Launcher ระดับรูทใน Android 12 (ระดับ API 31) ขึ้นไป

  • กิจกรรมสามารถสร้างอินสแตนซ์ได้หลายครั้ง แม้จะมาจากงานอื่นๆ ก็ตาม

จัดการงานต่างๆ

Android จะจัดการงานและ Back Stack โดยวางกิจกรรมทั้งหมดที่เริ่มติดต่อกันไว้ในงานเดียวกันในสแต็กแบบเข้าทีหลังออกก่อน วิธีนี้ใช้ได้ดีกับแอปส่วนใหญ่ และโดยปกติแล้วคุณไม่ต้องกังวลว่ากิจกรรมจะเชื่อมโยงกับงานอย่างไรหรือมีอยู่ใน Back Stack อย่างไร

อย่างไรก็ตาม คุณอาจตัดสินใจว่าต้องการขัดจังหวะลักษณะการทำงานตามปกติ ตัวอย่างเช่น คุณอาจต้องการให้กิจกรรมในแอปเริ่มงานใหม่เมื่อเริ่มต้น แทนที่จะวางไว้ในงานปัจจุบัน หรือเมื่อเริ่มกิจกรรม คุณอาจต้องการนำอินสแตนซ์ที่มีอยู่ของกิจกรรมนั้นมาใช้ แทนที่จะสร้างอินสแตนซ์ใหม่ที่ด้านบนของ Back Stack หรือคุณอาจต้องการให้ Back Stack ล้างกิจกรรมทั้งหมด ยกเว้นกิจกรรมรูทเมื่อผู้ใช้ออกจากงาน

คุณสามารถทำสิ่งเหล่านี้และอื่นๆ ได้โดยใช้แอตทริบิวต์ในองค์ประกอบไฟล์ Manifest <activity> และแฟล็กใน Intent ที่คุณส่งไปยัง startActivity()

แอตทริบิวต์ <activity> หลักที่คุณใช้จัดการงานได้มีดังนี้

และนี่คือแฟล็ก Intent หลักที่คุณใช้ได้

ส่วนต่อไปนี้จะอธิบายวิธีใช้แอตทริบิวต์ไฟล์ Manifest และแฟล็ก Intent เหล่านี้เพื่อกำหนดวิธีที่กิจกรรมเชื่อมโยงกับงานและลักษณะการทำงานใน Back Stack

ส่วนต่อไปนี้ยังกล่าวถึงวิธีที่ระบบแสดงและจัดการงานและกิจกรรมในหน้าจอล่าสุดด้วย โดยปกติแล้ว คุณจะปล่อยให้ระบบกำหนดวิธีแสดงงานและกิจกรรมในหน้าจอล่าสุด และไม่จำเป็นต้องแก้ไขลักษณะการทำงานนี้ ดูข้อมูลเพิ่มเติมได้ที่หน้าจอล่าสุด

กำหนดโหมดเปิดใช้งาน

โหมดเปิดใช้งานช่วยให้คุณกำหนดวิธีเชื่อมโยงอินสแตนซ์ใหม่ของกิจกรรมกับงานปัจจุบันได้ คุณกำหนดโหมดเปิดใช้งานได้ 2 วิธี ซึ่งอธิบายไว้ในส่วนต่อไปนี้

  • การใช้ไฟล์ Manifest

    เมื่อประกาศกิจกรรมในไฟล์ Manifest คุณสามารถระบุวิธีที่กิจกรรมเชื่อมโยงกับงานเมื่อเริ่มต้นได้

  • การใช้แฟล็ก Intent

    เมื่อเรียกใช้ startActivity() คุณสามารถใส่ Flag ใน Intent ที่ประกาศวิธี (หรือว่าจะ) เชื่อมโยงกิจกรรมใหม่กับงานปัจจุบันหรือไม่

ดังนั้น หากกิจกรรม A เริ่มกิจกรรม B กิจกรรม B จะกำหนดในไฟล์ Manifest ได้ว่าจะเชื่อมโยงกับงานปัจจุบันอย่างไร และกิจกรรม A จะใช้แฟล็ก Intent เพื่อขอวิธีที่กิจกรรม B จะเชื่อมโยงกับงานปัจจุบันได้

หากทั้ง 2 กิจกรรมกำหนดวิธีที่กิจกรรม B เชื่อมโยงกับงาน คำขอของกิจกรรม A ตามที่กำหนดไว้ใน Intent จะได้รับความสำคัญเหนือคำขอของกิจกรรม B ตามที่กำหนดไว้ในไฟล์ Manifest

กำหนดโหมดเปิดใช้งานโดยใช้ไฟล์ Manifest

เมื่อประกาศกิจกรรมในไฟล์ Manifest คุณสามารถระบุวิธีเชื่อมโยงกิจกรรมกับงานโดยใช้แอตทริบิวต์ launchMode ขององค์ประกอบ <activity>

คุณสามารถกำหนดโหมดเปิดใช้งานให้กับแอตทริบิวต์ launchMode ได้ 5 โหมด ดังนี้

  1. "standard"
    โหมดเริ่มต้น ระบบจะสร้างอินสแตนซ์ใหม่ของกิจกรรมในงานที่เริ่มต้นกิจกรรมนั้นและกำหนดเส้นทาง Intent ไปยังกิจกรรมดังกล่าว กิจกรรมสามารถสร้างอินสแตนซ์ได้หลายครั้ง โดยแต่ละอินสแตนซ์อาจเป็นของงานที่แตกต่างกัน และงานหนึ่งๆ อาจมีหลายอินสแตนซ์
  2. "singleTop"
    หากมีอินสแตนซ์ของกิจกรรมอยู่ที่ด้านบนของงานปัจจุบันอยู่แล้ว ระบบจะกำหนดเส้นทาง Intent ไปยังอินสแตนซ์นั้นผ่านการเรียกใช้เมธอด onNewIntent() แทนที่จะสร้างอินสแตนซ์ใหม่ของกิจกรรม กิจกรรมจะสร้างอินสแตนซ์หลายครั้ง โดยแต่ละอินสแตนซ์อาจเป็นของงานที่แตกต่างกัน และงานหนึ่งอาจมีหลายอินสแตนซ์ (แต่เฉพาะในกรณีที่กิจกรรมที่ด้านบนของ Back Stack ไม่ใช่อินสแตนซ์ที่มีอยู่ของกิจกรรม)

    ตัวอย่างเช่น สมมติว่า Back Stack ของงานประกอบด้วยกิจกรรมรูท A โดยมีกิจกรรม B, C และ D อยู่ด้านบน (ดังนั้นสแต็กคือ A-B-C-D โดยมี D อยู่ด้านบน) Intent จะมาถึงสำหรับกิจกรรมประเภท D หาก D มีโหมดเปิดใช้งาน "standard" เริ่มต้น ระบบจะเปิดใช้งานอินสแตนซ์ใหม่ของคลาส และสแต็กจะกลายเป็น A-B-C-D-D อย่างไรก็ตาม หากโหมดเปิดใช้งานของ D คือ "singleTop" อินสแตนซ์ที่มีอยู่ของ D จะได้รับ Intent ผ่าน onNewIntent() เนื่องจากอยู่ที่ด้านบนของสแต็ก และสแต็กจะยังคงเป็น A-B-C-D ในทางกลับกัน หาก Intent มาถึงสำหรับกิจกรรมประเภท B ระบบจะเพิ่มอินสแตนซ์ใหม่ของ B ลงในสแต็กแม้ว่าโหมดเปิดใช้งานจะเป็น "singleTop" ก็ตาม

  3. "singleTask"
    ระบบจะสร้างกิจกรรมที่รูทของงานใหม่หรือค้นหากิจกรรมในงานที่มีอยู่ซึ่งมีความเกี่ยวข้องเหมือนกัน หากมีอินสแตนซ์ของกิจกรรมอยู่แล้ว ระบบจะกำหนดเส้นทาง Intent ไปยังอินสแตนซ์ที่มีอยู่ผ่านการเรียกใช้เมธอด onNewIntent() แทนการสร้างอินสแตนซ์ใหม่ ในขณะเดียวกัน กิจกรรมอื่นๆ ทั้งหมดที่อยู่ด้านบนจะถูกทำลาย
  4. "singleInstance"
    ลักษณะการทำงานจะเหมือนกับ "singleTask" ยกเว้นว่าระบบจะไม่เปิดกิจกรรมอื่นๆ ในงานที่มีอินสแตนซ์อยู่ กิจกรรมจะเป็นสมาชิกเพียงหนึ่งเดียวของงานเสมอ กิจกรรมที่เริ่มต้นโดยกิจกรรมนี้จะเปิดในงานแยกต่างหาก
  5. "singleInstancePerTask"
    กิจกรรมจะทำงานเป็นกิจกรรมรูทของงานได้เท่านั้น ซึ่งเป็นกิจกรรมแรกที่สร้างงาน ดังนั้นจึงมีกิจกรรมนี้ได้เพียงรายการเดียวในงาน กิจกรรมนี้จะเริ่มได้ในหลายอินสแตนซ์ในงานที่ต่างกันหากมีการตั้งค่าแฟล็ก FLAG_ACTIVITY_MULTIPLE_TASK หรือ FLAG_ACTIVITY_NEW_DOCUMENT ซึ่งต่างจากโหมดเปิดใช้งาน singleTask

ตัวอย่างเช่น เบราว์เซอร์ Android ระบุ singleTask ใน <activity> ดังนั้นกิจกรรมของเบราว์เซอร์จึงไม่ได้อยู่ในงานของแอป แต่จะเริ่มงานใหม่สำหรับเบราว์เซอร์หรือนำงานเบื้องหลังของเบราว์เซอร์ที่มีอยู่มาไว้ข้างหน้าแทน

ไม่ว่ากิจกรรมจะเริ่มต้นในงานใหม่หรือในงานเดียวกับกิจกรรมที่เริ่มต้นกิจกรรมนั้น ปุ่มย้อนกลับและท่าทางสัมผัสจะนำผู้ใช้ไปยังกิจกรรมก่อนหน้าเสมอ อย่างไรก็ตาม หากคุณเริ่มกิจกรรมที่ระบุโหมดเปิดใช้งาน singleTask และอินสแตนซ์ของกิจกรรมนั้นมีอยู่ในงานที่ทำงานอยู่เบื้องหลัง ระบบจะนำงานทั้งหมดนั้นมาไว้ที่เบื้องหน้า ณ จุดนี้ Back Stack จะรวมกิจกรรมทั้งหมดจากงานที่นำมาไว้ที่ด้านบนของสแต็ก รูปที่ 4 แสดงสถานการณ์ประเภทนี้

รูปที่ 4 การแสดงวิธีเพิ่มกิจกรรมที่มีโหมดเปิดใช้งาน "singleTask" ลงใน Back Stack หากกิจกรรมเป็นส่วนหนึ่งของงานที่ทำงานอยู่เบื้องหลังซึ่งมี Back Stack ของตัวเองอยู่แล้ว Back Stack ทั้งหมดนั้นก็จะปรากฏขึ้นที่ด้านบนของงานปัจจุบันด้วย

ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้โหมดเปิดใช้งานในไฟล์ Manifest ได้ที่เอกสารประกอบเกี่ยวกับองค์ประกอบ <activity>

กำหนดโหมดเปิดใช้งานโดยใช้แฟล็ก Intent

เมื่อเริ่มกิจกรรม คุณสามารถแก้ไขการเชื่อมโยงเริ่มต้นของกิจกรรมกับงานได้โดยใส่ Flag ใน Intent ที่คุณส่งไปยัง startActivity() แฟล็กที่คุณใช้เพื่อแก้ไขลักษณะการทำงานเริ่มต้นมีดังนี้

FLAG_ACTIVITY_NEW_TASK

ระบบจะเริ่มกิจกรรมในงานใหม่ หากมีงานที่ทำงานอยู่แล้วสำหรับกิจกรรมที่กำลังเริ่มต้น งานนั้นจะถูกนำมาไว้ที่เบื้องหน้าโดยมีการกู้คืนสถานะล่าสุด และกิจกรรมจะได้รับ Intent ใหม่ใน onNewIntent()

ซึ่งจะทำให้เกิดลักษณะการทำงานเดียวกันกับค่า "singleTask" launchMode ที่กล่าวถึงในส่วนก่อนหน้า

FLAG_ACTIVITY_SINGLE_TOP

หากกิจกรรมที่เริ่มเป็นกิจกรรมปัจจุบันที่ด้านบนของ Back Stack อินสแตนซ์ที่มีอยู่จะได้รับการเรียกไปยัง onNewIntent() แทนที่จะสร้างอินสแตนซ์ใหม่ของกิจกรรม

ซึ่งจะทำให้เกิดลักษณะการทำงานเดียวกันกับค่า "singleTop" launchMode ที่กล่าวถึงในส่วนก่อนหน้า

FLAG_ACTIVITY_CLEAR_TOP

หากกิจกรรมที่เริ่มต้นทำงานอยู่แล้วในงานปัจจุบัน ระบบจะทำลายกิจกรรมอื่นๆ ทั้งหมดที่อยู่ด้านบนแทนที่จะเปิดอินสแตนซ์ใหม่ของกิจกรรมนั้น ระบบจะส่ง Intent ไปยังอินสแตนซ์ที่กลับมาทำงานอีกครั้งของกิจกรรม ซึ่งตอนนี้อยู่ที่ด้านบน ผ่าน onNewIntent()

แอตทริบิวต์ launchMode ไม่มีค่าที่ทำให้เกิดลักษณะการทำงานนี้

FLAG_ACTIVITY_CLEAR_TOP มักใช้ร่วมกับ FLAG_ACTIVITY_NEW_TASK มากที่สุด เมื่อใช้ร่วมกัน แฟล็กเหล่านี้จะค้นหากิจกรรมที่มีอยู่ในงานอื่นและวางไว้ในตำแหน่งที่สามารถตอบสนองต่อ Intent ได้

จัดการความสัมพันธ์

ความสัมพันธ์จะระบุว่ากิจกรรม "ต้องการ" เป็นของงานใด โดยค่าเริ่มต้น กิจกรรมทั้งหมดจากแอปเดียวกันจะมีความสัมพันธ์กัน กล่าวคือ กิจกรรมเหล่านั้น "ต้องการ" อยู่ในงานเดียวกัน

อย่างไรก็ตาม คุณสามารถแก้ไขความสัมพันธ์เริ่มต้นสําหรับกิจกรรมได้ กิจกรรมที่กำหนดไว้ในแอปต่างๆ สามารถแชร์ความสัมพันธ์ได้ และกิจกรรมที่กำหนดไว้ในแอปเดียวกันสามารถกำหนดความสัมพันธ์ของงานที่แตกต่างกันได้

คุณแก้ไขความเกี่ยวข้องของกิจกรรมได้โดยใช้แอตทริบิวต์ taskAffinity ขององค์ประกอบ <activity>

แอตทริบิวต์ taskAffinity จะใช้ค่าสตริงที่ต้องแตกต่างจากชื่อแพ็กเกจเริ่มต้นที่ประกาศไว้ในองค์ประกอบ <manifest> เนื่องจากระบบใช้ชื่อนั้นเพื่อระบุความสัมพันธ์ของงานเริ่มต้นสำหรับแอป

ความสัมพันธ์จะมีบทบาทใน 2 สถานการณ์ต่อไปนี้

  1. เมื่อ Intent ที่เปิดกิจกรรมมีแฟล็ก FLAG_ACTIVITY_NEW_TASK

    โดยค่าเริ่มต้น กิจกรรมใหม่จะเปิดขึ้นในงานของกิจกรรมที่เรียกใช้ startActivity() ระบบจะพุชกิจกรรมดังกล่าวไปยัง Back Stack เดียวกันกับผู้โทร

    อย่างไรก็ตาม หาก Intent ที่ส่งไปยัง startActivity() มีแฟล็ก FLAG_ACTIVITY_NEW_TASK ระบบจะมองหางานอื่นเพื่อจัดเก็บกิจกรรมใหม่ ซึ่งมักจะเป็นงานใหม่ แต่ก็ไม่จำเป็นต้องเป็นเช่นนั้นเสมอไป หากมีงานที่มีอยู่ซึ่งมีความเกี่ยวข้องเหมือนกับกิจกรรมใหม่ ระบบจะเปิดกิจกรรมในงานนั้น หากไม่ ระบบจะเริ่มงานใหม่

    หากแฟล็กนี้ทำให้กิจกรรมเริ่มงานใหม่และผู้ใช้ใช้ปุ่มหน้าแรกหรือท่าทางสัมผัสเพื่อออกจากงานนั้น ผู้ใช้ต้องมีวิธีกลับไปยังงานดังกล่าว เอนทิตีบางรายการ เช่น ตัวจัดการการแจ้งเตือน จะเริ่มกิจกรรมในงานภายนอกเสมอ ไม่เคยเป็นส่วนหนึ่งของงานของตนเอง ดังนั้นจึงใส่ FLAG_ACTIVITY_NEW_TASK ไว้ใน Intent ที่ส่งไปยัง startActivity() เสมอ

    หากเอนทิตีภายนอกเรียกใช้กิจกรรมของคุณด้วยแฟล็กนี้ได้ ให้ผู้ใช้มีวิธีกลับมาอย่างอิสระ เช่น ไอคอน Launcher จากตัวกรอง CATEGORY_LAUNCHER ในกิจกรรมรูทของงาน ดูข้อมูลเพิ่มเติมได้ที่หัวข้อเริ่มงาน

  2. เมื่อกิจกรรมมีแอตทริบิวต์ allowTaskReparenting ตั้งค่าเป็น "true"

    ในกรณีนี้ กิจกรรมสามารถย้ายจากงานที่เริ่มต้นไปยังงานที่มีความเกี่ยวข้องเมื่อมีการนำงานนั้นมาไว้ที่เบื้องหน้า

    ตัวอย่างเช่น สมมติว่ากิจกรรมที่รายงานสภาพอากาศในเมืองที่เลือกได้รับการกำหนดให้เป็นส่วนหนึ่งของแอปการเดินทาง กิจกรรมนี้มีความสัมพันธ์เหมือนกับกิจกรรมอื่นๆ ในแอปเดียวกัน ซึ่งเป็นความสัมพันธ์ของแอปเริ่มต้น และสามารถกำหนดระดับชั้นใหม่ได้ด้วยแอตทริบิวต์นี้

    เมื่อกิจกรรมหนึ่งของคุณเริ่มกิจกรรมผู้รายงานสภาพอากาศ ในตอนแรกกิจกรรมนั้นจะอยู่ในงานเดียวกับกิจกรรมของคุณ อย่างไรก็ตาม เมื่อ Task ของแอปการเดินทางมาอยู่เบื้องหน้า กิจกรรมรายงานสภาพอากาศจะได้รับการกำหนดใหม่ให้กับ Task นั้นและแสดงภายใน Task นั้น

ล้าง Back Stack

หากผู้ใช้ออกจากงานเป็นเวลานาน ระบบจะล้างงานของกิจกรรมทั้งหมด ยกเว้นกิจกรรมรูท เมื่อผู้ใช้กลับมาที่งาน ระบบจะกู้คืนเฉพาะกิจกรรมรูทเท่านั้น ระบบจะทำงานในลักษณะนี้โดยอิงตามสมมติฐานที่ว่าหลังจากผ่านไประยะเวลาหนึ่ง ผู้ใช้จะละทิ้งสิ่งที่ทำอยู่ก่อนหน้านี้และกลับมาที่งานเพื่อเริ่มทำสิ่งใหม่

คุณใช้แอตทริบิวต์กิจกรรมบางอย่างเพื่อแก้ไขลักษณะการทำงานนี้ได้ ดังนี้

alwaysRetainTaskState
เมื่อตั้งค่าแอตทริบิวต์นี้เป็น "true" ในกิจกรรมรูทของงาน ลักษณะการทำงานเริ่มต้นที่อธิบายไว้จะไม่เกิดขึ้น งานจะเก็บกิจกรรมทั้งหมดไว้ในสแต็กแม้ว่าจะผ่านไปเป็นเวลานาน
clearTaskOnLaunch

เมื่อตั้งค่าแอตทริบิวต์นี้เป็น "true" ในกิจกรรมรูทของงาน ระบบจะล้างงานลงในกิจกรรมรูททุกครั้งที่ผู้ใช้ออกจากงานและกลับมาที่งาน กล่าวคือ เป็นสิ่งที่ตรงกันข้ามกับ alwaysRetainTaskState ผู้ใช้จะกลับไปที่งานในสถานะเริ่มต้นเสมอ แม้ว่าจะออกจากงานไปเพียงครู่เดียวก็ตาม

finishOnTaskLaunch

แอตทริบิวต์นี้คล้ายกับ clearTaskOnLaunch แต่จะทำงานกับกิจกรรมเดียว ไม่ใช่ทั้งงาน นอกจากนี้ยังทำให้กิจกรรมทั้งหมดเสร็จสิ้นได้ ยกเว้นกิจกรรมรูท เมื่อตั้งค่าเป็น "true" กิจกรรมจะยังคงเป็นส่วนหนึ่งของงานสำหรับเซสชันปัจจุบันเท่านั้น หากผู้ใช้ออกจากงานแล้วกลับมาอีกครั้ง งานนั้นจะไม่อยู่แล้ว

เริ่มงาน

คุณสามารถตั้งค่ากิจกรรมเป็นจุดแรกเข้าสำหรับงานได้โดยให้ตัวกรอง Intent ที่มี "android.intent.action.MAIN" เป็นการดำเนินการที่ระบุและ "android.intent.category.LAUNCHER" เป็นหมวดหมู่ที่ระบุ ดังนี้

<activity ... >
    <intent-filter ... >
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    ...
</activity>

ตัวกรอง Intent นี้จะแสดงไอคอนและป้ายกำกับสำหรับกิจกรรมในตัวเปิดแอป ซึ่งช่วยให้ผู้ใช้เปิดกิจกรรมและกลับไปที่งานที่สร้างขึ้นได้

ความสามารถที่ 2 นี้มีความสำคัญ ผู้ใช้ต้องออกจากงานและกลับมาทำต่อในภายหลังได้โดยใช้ตัวเปิดกิจกรรมนี้ ด้วยเหตุนี้ ให้ใช้โหมดเปิดใช้งาน 2 โหมดที่ทำเครื่องหมายกิจกรรมว่าเริ่มต้นงานเสมอ ได้แก่ "singleTask" และ "singleInstance" เมื่อกิจกรรมมีตัวกรอง ACTION_MAIN และ CATEGORY_LAUNCHER

ลองนึกภาพสิ่งที่จะเกิดขึ้นหากไม่มีตัวกรอง เช่น Intent เปิดใช้งานกิจกรรม "singleTask" โดยเริ่มงานใหม่ และผู้ใช้ใช้เวลาทำงานนั้น จากนั้นผู้ใช้จะใช้ปุ่มหน้าแรกหรือท่าทางสัมผัส ตอนนี้ระบบจะส่งงานไปยังเบื้องหลังและไม่แสดงให้เห็น ตอนนี้ผู้ใช้ไม่มีทางกลับไปที่งานได้ เนื่องจากงานไม่ได้แสดงในตัวเปิดแอป

ในกรณีที่คุณไม่ต้องการให้ผู้ใช้กลับไปที่กิจกรรมได้ ให้ตั้งค่า finishOnTaskLaunch ขององค์ประกอบ <activity> เป็น "true" ดูข้อมูลเพิ่มเติมได้ที่ล้าง Back Stack

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีแสดงและจัดการงานและกิจกรรมในหน้าจอล่าสุดได้ที่หน้าจอล่าสุด

แหล่งข้อมูลเพิ่มเติม