วงจรชีวิตของกิจกรรม

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

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

Callback แต่ละรายการช่วยให้คุณทำงานเฉพาะที่เหมาะสมกับการเปลี่ยนแปลงสถานะที่กำหนดได้ การทำงานที่เหมาะสมในเวลาที่เหมาะสมและการจัดการการเปลี่ยนผ่านอย่างเหมาะสมจะทำให้แอปของคุณมีประสิทธิภาพและเสถียรมากขึ้น ตัวอย่างเช่น การใช้ Lifecycle Callback ที่ดีจะช่วยให้แอปหลีกเลี่ยงสิ่งต่อไปนี้ได้

  • ขัดข้องหากผู้ใช้รับสายโทรศัพท์หรือสลับไปใช้แอปอื่นขณะใช้แอปของคุณ
  • ใช้ทรัพยากรระบบที่มีค่าเมื่อผู้ใช้ไม่ได้ใช้งานอยู่
  • การสูญเสียความคืบหน้าของผู้ใช้หากผู้ใช้ออกจากแอปและกลับมาในภายหลัง
  • ขัดข้องหรือสูญเสียความคืบหน้าของผู้ใช้เมื่อหน้าจอหมุนระหว่างการวางแนวแนวนอนและแนวตั้ง

เอกสารนี้จะอธิบายวงจรกิจกรรมโดยละเอียด เอกสารเริ่มต้นด้วยการอธิบายกระบวนทัศน์ของวงจรการใช้งาน จากนั้นจะอธิบาย Callback แต่ละรายการว่าเกิดอะไรขึ้นภายในขณะที่ Callback ทำงาน และสิ่งที่คุณต้องทำในระหว่างนั้น

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

ดูข้อมูลเกี่ยวกับการจัดการวงจร รวมถึงคำแนะนำเกี่ยวกับแนวทางปฏิบัติแนะนำได้ที่วงจรใน Jetpack Compose และบันทึกสถานะ UI หากต้องการดูวิธีออกแบบแอปที่มีประสิทธิภาพและมีคุณภาพระดับเวอร์ชันที่ใช้งานจริงโดยใช้กิจกรรมร่วมกับคอมโพเนนต์สถาปัตยกรรม โปรดดูคู่มือสถาปัตยกรรมแอป

แนวคิดเกี่ยวกับวงจรกิจกรรม

หากต้องการไปยังส่วนต่างๆ ของการเปลี่ยนผ่านระหว่างระยะต่างๆ ของวงจรกิจกรรม คลาส Activity จะมีชุด Callback หลัก 6 ชุด ได้แก่ onCreate, onStart, onResume, onPause, onStop และ onDestroy ระบบจะเรียกใช้ Callback แต่ละรายการเหล่านี้เมื่อกิจกรรมเข้าสู่สถานะใหม่

รูปที่ 1 แสดงภาพของกระบวนทัศน์นี้

รูปที่ 1 ภาพประกอบแบบง่ายของวงจรกิจกรรม

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

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

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

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

Compose และวงจร

ใน Compose ให้หลีกเลี่ยงการวางตรรกะทางธุรกิจหรือการตั้งค่าผู้สังเกตการณ์ด้วยตนเองโดยตรงภายใน Callback ของกิจกรรม เช่น onStart หรือ onResume แต่ให้ใช้เอฟเฟกต์ที่รับรู้วงจรชีวิตและผู้สังเกตการณ์ที่รับรู้สถานะซึ่งจะปรับให้สอดคล้องกับการแสดงผลของ UI บนหน้าจอโดยอัตโนมัติแทน

  • คอลเล็กชันที่รับรู้ถึงวงจร: ใช้ collectAsStateWithLifecycle เพื่อใช้โฟลว์จาก ViewModel API นี้จะเริ่มรวบรวมข้อมูลโดยอัตโนมัติเมื่อ UI เข้าสู่สถานะ "เริ่มต้น" และหยุดเมื่อ UI เข้าสู่เบื้องหลัง เพื่อป้องกันการใช้ทรัพยากรโดยไม่จำเป็น หลังจากรวบรวมโฟลว์เป็นสถานะแล้ว คุณสามารถใช้ LifecycleEffects เพื่อเรียกใช้โค้ดเมื่อเกิดเหตุการณ์ในวงจรได้
  • ขั้นตอนของตรรกะ: การใช้ API เหล่านี้ทำให้ UI ตอบสนองต่อสถานะวงจรอย่างเป็นธรรมชาติผ่านแผนผังองค์ประกอบ เพื่อให้มั่นใจว่าตรรกะทางธุรกิจจะทำงานเมื่อผู้ใช้โต้ตอบกับคอมโพเนนต์อยู่เท่านั้น

ดูข้อมูลเพิ่มเติมเกี่ยวกับ Compose และวงจรได้ที่วงจรใน Jetpack Compose

Lifecycle Callback

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

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

onCreate

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

ตัวอย่างเช่น การติดตั้งใช้งาน onCreate อาจเชื่อมโยงข้อมูลกับรายการ เชื่อมโยงกิจกรรมกับ ViewModel และสร้างอินสแตนซ์ตัวแปรขอบเขตคลาสบางรายการ เมธอดนี้จะรับพารามิเตอร์ savedInstanceState ซึ่งเป็นออบเจ็กต์ Bundle ที่มีสถานะที่บันทึกไว้ก่อนหน้านี้ของกิจกรรม หากไม่เคยมีกิจกรรมมาก่อน ค่าของออบเจ็กต์ Bundle จะเป็น Null

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

ตัวอย่างต่อไปนี้แสดงวิธีผสานรวม Composable ของ Text ในกิจกรรมที่เรียบง่ายที่สุด

class ExampleActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent { // In here, we can call composables!
            MaterialTheme {
                Greeting(name = "compose")
            }
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

กิจกรรมของคุณไม่อยู่ในสถานะ "สร้างแล้ว" หลังจากเมธอด onCreate ทำงานเสร็จแล้ว กิจกรรมจะเข้าสู่สถานะเริ่มต้น และระบบจะเรียกใช้เมธอด onStart และ onResume ต่อเนื่องกันอย่างรวดเร็ว

onStart

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

เมื่อกิจกรรมเปลี่ยนเป็นสถานะ "เริ่มต้น" คอมโพเนนต์ที่รับรู้ถึงวงจรซึ่งเชื่อมโยงกับวงจรของกิจกรรมจะได้รับเหตุการณ์ ON_START

เมธอด onStart จะเสร็จสมบูรณ์อย่างรวดเร็ว และเช่นเดียวกับสถานะ Created กิจกรรมจะไม่อยู่ในสถานะ Started เมื่อ Callback นี้เสร็จสิ้น กิจกรรมจะเข้าสู่สถานะกลับมาทำงานต่อ และระบบจะเรียกใช้เมธอด onResume

onResume

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

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

เมื่อเกิดเหตุการณ์ที่ขัดจังหวะ กิจกรรมจะเข้าสู่สถานะหยุดชั่วคราว และระบบจะเรียกใช้ Callback onPause

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

ต่อไปนี้คือตัวอย่างคอมโพเนนต์ที่รับรู้ถึงวงจรชีวิตซึ่งเข้าถึงกล้องเมื่อคอมโพเนนต์ได้รับเหตุการณ์ ON_RESUME

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun initializeCamera() {
        if (camera == null) {
            getCamera()
        }
    }
    ...
}

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

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

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

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

ไม่ว่าคุณจะเลือกเหตุการณ์การสร้างใดเพื่อดำเนินการเริ่มต้น ให้ตรวจสอบว่าได้ใช้เหตุการณ์ในวงจรที่เกี่ยวข้องเพื่อปล่อยทรัพยากร หากคุณเริ่มต้นบางอย่างหลังจากเหตุการณ์ ON_START ให้ปล่อยหรือสิ้นสุดหลังจากเหตุการณ์ ON_STOP หากคุณเริ่มต้นหลังจากเหตุการณ์ ON_RESUME ให้ปล่อยหลังจากเหตุการณ์ ON_PAUSE

ข้อมูลโค้ดก่อนหน้าจะวางโค้ดการเริ่มต้นกล้องไว้ในคอมโพเนนต์ที่รับรู้ถึงวงจร คุณสามารถใส่โค้ดนี้ลงใน Lifecycle Callback ของวงจรกิจกรรมโดยตรง เช่น onStart และ onStop แต่เราไม่แนะนำให้ทำเช่นนี้ การเพิ่มตรรกะนี้ลงในคอมโพเนนต์ที่รับรู้ถึงวงจรชีวิตแบบอิสระช่วยให้คุณนำคอมโพเนนต์กลับมาใช้ซ้ำในกิจกรรมต่างๆ ได้โดยไม่ต้องทำซ้ำโค้ด ดูวิธีสร้างคอมโพเนนต์ที่รับรู้ถึงวงจรได้ที่วงจรใน Jetpack Compose

onPause

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

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

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

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

นอกจากนี้ คุณยังใช้เมธอด onPause เพื่อปล่อยทรัพยากรระบบ แฮนเดิลไปยังเซ็นเซอร์ (เช่น GPS) หรือทรัพยากรใดๆ ที่ส่งผลต่ออายุการใช้งานแบตเตอรี่ขณะที่กิจกรรมหยุดชั่วคราวและผู้ใช้ไม่ต้องการใช้ได้ด้วย

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

ตัวอย่างต่อไปนี้ของ LifecycleObserver ที่ตอบสนองต่อเหตุการณ์ ON_PAUSE เป็นตัวอย่างที่ตรงกันกับตัวอย่างเหตุการณ์ ON_RESUME ก่อนหน้า ซึ่งจะปล่อยกล้องที่เริ่มต้นหลังจากได้รับเหตุการณ์ ON_RESUME

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun releaseCamera() {
        camera?.release()
        camera = null
    }
    ...
}

ตัวอย่างนี้จะวางโค้ดการปล่อยกล้องหลังจากที่ LifecycleObserver ได้รับเหตุการณ์ ON_PAUSE

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

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

การดำเนินการตามเมธอด onPause เสร็จสมบูรณ์ไม่ได้หมายความว่ากิจกรรมจะออกจากสถานะหยุดชั่วคราว แต่กิจกรรมจะยังคงอยู่ในสถานะนี้จนกว่ากิจกรรมจะกลับมาทำงานอีกครั้งหรือผู้ใช้มองไม่เห็นกิจกรรมโดยสมบูรณ์ หากกิจกรรมกลับมาทำงานอีกครั้ง ระบบจะเรียกใช้ Callback onResume อีกครั้ง

หากกิจกรรมกลับจากสถานะ "หยุดชั่วคราว" เป็นสถานะ "กลับมาทำงานอีกครั้ง" ระบบจะเก็บอินสแตนซ์ Activity ไว้ในหน่วยความจำ โดยจะเรียกใช้อินสแตนซ์นั้นอีกครั้งเมื่อระบบเรียกใช้ onResume ในกรณีนี้ คุณไม่จำเป็นต้องเริ่มต้นคอมโพเนนต์ที่สร้างขึ้นในระหว่างเมธอด Callback ใดๆ ที่นำไปสู่สถานะกลับมาทำงานอีกครั้ง หากกิจกรรมไม่ปรากฏให้เห็นเลย ระบบจะเรียกใช้ onStop

onStop

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

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

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

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

override fun onStop() {
    super.onStop()

    // Delegate the save operation to the ViewModel, which handles the
    // background thread operations (e.g., using Kotlin Coroutines and Room).
    noteViewModel.saveDraft()
}

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

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

onDestroy

ระบบจะเรียกใช้ onDestroy ก่อนที่กิจกรรมจะถูกทำลาย ระบบจะเรียกใช้ Callback นี้ด้วยเหตุผลข้อใดข้อหนึ่งต่อไปนี้

  1. กิจกรรมกำลังจะสิ้นสุดลงเนื่องจากผู้ใช้ปิดกิจกรรมโดยสมบูรณ์หรือเนื่องจากมีการเรียกใช้ finish ในกิจกรรม
  2. ระบบกำลังทำลายกิจกรรมชั่วคราวเนื่องจากมีการเปลี่ยนแปลงการกำหนดค่า เช่น การหมุนอุปกรณ์หรือการเข้าสู่โหมดหลายหน้าต่าง

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

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

หากไม่มีการสร้าง Activity ขึ้นมาใหม่ ระบบจะเรียกใช้เมธอด onCleared ใน ViewModel ซึ่งจะล้างข้อมูลที่จำเป็นก่อนที่จะถูกทำลาย คุณแยกความแตกต่างระหว่าง 2 สถานการณ์นี้ได้ด้วยเมธอด isFinishing

หากกิจกรรมกำลังจะเสร็จสิ้น onDestroy จะเป็น Lifecycle Callback สุดท้ายที่กิจกรรมได้รับ หากมีการเรียกใช้ onDestroy อันเป็นผลมาจากการเปลี่ยนแปลงการกำหนดค่า ระบบจะสร้างอินสแตนซ์กิจกรรมใหม่ทันที แล้วเรียกใช้ onCreate ในอินสแตนซ์ใหม่นั้นในการกำหนดค่าใหม่

Callback onDestroy จะปล่อยทรัพยากรทั้งหมดที่ Callback ก่อนหน้าไม่ได้ปล่อย เช่น onStop

สถานะกิจกรรมและการนำออกจากหน่วยความจำ

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

ความเป็นไปได้ที่จะถูกฆ่า

สถานะการประมวลผล

สถานะกิจกรรมสุดท้าย

ต่ำสุด

เบื้องหน้า (มีหรือกำลังจะได้รับโฟกัส)

กลับมาทำงานอีกครั้ง

ต่ำ

มองเห็นได้ (ไม่มีโฟกัส)

เริ่ม/หยุดชั่วคราว

สูงขึ้น

พื้นหลัง (มองไม่เห็น)

หยุดทำงานแล้ว

สูงสุด

ว่าง

ทำลายแล้ว

ตาราง 1. ความสัมพันธ์ระหว่างวงจรของกระบวนการและสถานะกิจกรรม

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

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับกระบวนการได้ที่ภาพรวมกระบวนการและชุดข้อความ

การบันทึกและการกู้คืนสถานะ UI ชั่วคราว

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

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

เมื่อข้อจำกัดของระบบทำลายกิจกรรม ให้คงสถานะ UI ชั่วคราวของผู้ใช้ไว้โดยใช้ ViewModel (สำหรับตรรกะทางธุรกิจที่ซับซ้อนและสถานะหน้าจอ), Jetpack Compose rememberSaveable API (สำหรับสถานะ UI ที่มีน้ำหนักเบา) และ/หรือพื้นที่เก็บข้อมูลในเครื่องร่วมกัน ดูข้อมูลเพิ่มเติมเกี่ยวกับความคาดหวังของผู้ใช้เมื่อเทียบกับลักษณะการทำงานของระบบ และวิธีเก็บรักษาข้อมูลสถานะ UI ที่ซับซ้อนในกิจกรรมที่ระบบเริ่มต้นและการสิ้นสุดการประมวลผลได้ที่บันทึกสถานะ UI

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

สถานะอินสแตนซ์

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

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

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

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

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

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

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

บันทึกสถานะ UI ที่เรียบง่ายและมีขนาดเล็กโดยใช้ rememberSaveable

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

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

var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) {
    mutableStateOf(
        TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length))
    )
}

หากต้องการบันทึกข้อมูลถาวร เช่น ค่ากำหนดของผู้ใช้หรือข้อมูลสำหรับฐานข้อมูล ให้ใช้โอกาสที่เหมาะสมเมื่อกิจกรรมของคุณอยู่เบื้องหน้า หากไม่มีโอกาสดังกล่าว ให้บันทึกข้อมูลถาวรในระหว่างเมธอด onStop

คืนค่าสถานะ UI ของกิจกรรมโดยใช้สถานะอินสแตนซ์ที่บันทึกไว้

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

var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) {
    mutableStateOf(
        TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length))
    )
}

กิจกรรมและการนำทาง

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

ดูวิธีใช้การนำทางที่ทันสมัยซึ่งเน้น Compose เป็นหลักได้ที่คู่มือสำหรับไลบรารี Navigation 3 ของ Jetpack Compose

การเริ่มกิจกรรมหนึ่งจากอีกกิจกรรมหนึ่ง

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

คุณสามารถเริ่มกิจกรรมใหม่โดยใช้เมธอด startActivity หรือ startActivityForResult ก็ได้ ทั้งนี้ขึ้นอยู่กับว่ากิจกรรมของคุณต้องการผลลัพธ์กลับมาจากกิจกรรมใหม่ที่กำลังจะเริ่มหรือไม่ ไม่ว่าในกรณีใด คุณจะต้องส่งออบเจ็กต์ Intent

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

startActivity

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

เมื่อทำงานภายในแอปพลิเคชันของคุณเอง คุณมักจะต้องเปิดกิจกรรมที่รู้จัก ตัวอย่างเช่น ข้อมูลโค้ดต่อไปนี้แสดงวิธีเปิดกิจกรรมที่ชื่อ SignInActivity

val context = LocalContext.current

Button(onClick = {
    val intent = Intent(context, SignInActivity::class.java)
    context.startActivity(intent)
}) {
    Text("Sign In")
}

การเริ่มกิจกรรมภายนอก

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

เพื่อให้บรรลุเป้าหมายนี้ คุณต้องใช้ออบเจ็กต์ Intent เพื่ออธิบายประเภทการดำเนินการที่ต้องการทำ และระบบจะเปิดกิจกรรมที่เหมาะสมจากแอปพลิเคชันอื่น

เช่น หากต้องการให้ผู้ใช้ส่งข้อความอีเมล คุณสามารถสร้าง Intent ต่อไปนี้ได้

val intent = Intent(Intent.ACTION_SEND).apply {
    putExtra(Intent.EXTRA_EMAIL, recipientArray)
}
startActivity(intent)

หากต้องการเปิดกิจกรรมภายนอกและรับผลลัพธ์กลับมา (เช่น ขอให้แอปกล้องถ่ายรูปและแสดงผลรูปภาพ) ให้ใช้ Activity Result API ที่ทันสมัยแทน Callback startActivityForResult ที่เลิกใช้งานแล้ว

กิจกรรมการประสานงาน

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

ลำดับของ Lifecycle Callback ได้รับการกำหนดไว้อย่างชัดเจน โดยเฉพาะเมื่อกิจกรรม 2 รายการอยู่ในกระบวนการเดียวกัน หรือกล่าวคืออยู่ในแอปเดียวกัน และกิจกรรมหนึ่งกำลังเริ่มอีกกิจกรรมหนึ่ง ลำดับการดำเนินการที่เกิดขึ้นเมื่อกิจกรรม ก เริ่มกิจกรรม ข มีดังนี้

  1. เมธอด onPause ของกิจกรรม A ทำงาน
  2. เมธอด onCreate, onStart และ onResume ของกิจกรรม B จะทำงานตามลำดับ ตอนนี้กิจกรรม B มีโฟกัสของผู้ใช้แล้ว
  3. หากกิจกรรม A ไม่ปรากฏบนหน้าจออีกต่อไป เมธอด onStop ของกิจกรรมจะทำงาน

ลำดับของ Lifecycle Callback นี้ช่วยให้คุณจัดการการเปลี่ยนผ่านของข้อมูลจากกิจกรรมหนึ่งไปยังอีกกิจกรรมหนึ่งได้

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับวงจรกิจกรรมได้ที่แหล่งข้อมูลเพิ่มเติมต่อไปนี้

ดูเนื้อหา