เมื่อผู้ใช้ไปยังส่วนต่างๆ ออกจาก และกลับมายังแอปของคุณ อินสแตนซ์ Activity ในแอปจะเปลี่ยนสถานะต่างๆ ในวงจรของอินสแตนซ์
คลาส Activity มี Callback หลายรายการที่ช่วยให้กิจกรรมทราบ
เมื่อสถานะเปลี่ยนแปลง หรือระบบกำลังสร้าง หยุด หรือกลับมาทำงานต่อ
ในกิจกรรม หรือทำลายกระบวนการที่กิจกรรมอยู่
ภายในเมธอด Lifecycle Callback คุณสามารถประกาศลักษณะการทำงานของกิจกรรมได้ เมื่อผู้ใช้ออกจากกิจกรรมและกลับเข้าสู่กิจกรรม เช่น หากคุณกำลังสร้าง วิดีโอเพลเยอร์แบบสตรีม คุณอาจหยุดวิดีโอชั่วคราวและปิดการเชื่อมต่อเครือข่าย เมื่อผู้ใช้เปลี่ยนไปใช้แอปอื่น เมื่อผู้ใช้กลับมา คุณสามารถ เชื่อมต่อเครือข่ายอีกครั้งและให้ผู้ใช้ดูวิดีโอต่อจากจุดเดิมได้
โดยแต่ละแฮนเดิลจะช่วยให้คุณทำงานเฉพาะเจาะจงที่เหมาะสมกับการเปลี่ยนแปลงสถานะที่กำหนดได้ การทำงานที่ถูกต้องในเวลาที่เหมาะสมและการจัดการการเปลี่ยนผ่าน อย่างเหมาะสมจะช่วยให้แอปของคุณมีประสิทธิภาพและทำงานได้ดียิ่งขึ้น ตัวอย่างเช่น การติดตั้งใช้งานการเรียกกลับของวงจรที่ถูกต้องจะช่วยให้แอปหลีกเลี่ยงสิ่งต่อไปนี้ได้
- แอปขัดข้องหากผู้ใช้รับสายโทรศัพท์หรือสลับไปใช้แอปอื่นขณะ ใช้แอปของคุณ
- ใช้ทรัพยากรระบบที่มีค่าเมื่อผู้ใช้ไม่ได้ใช้งานอยู่
- การสูญเสียความคืบหน้าของผู้ใช้หากผู้ใช้ออกจากแอปและกลับมาที่แอปในภายหลัง
- แอปขัดข้องหรือความคืบหน้าของผู้ใช้หายไปเมื่อหน้าจอหมุนระหว่างแนวนอนและแนวตั้ง
เอกสารนี้อธิบายวงจรกิจกรรมโดยละเอียด เอกสารนี้เริ่มต้นด้วย การอธิบายกระบวนทัศน์วงจรการใช้งาน จากนั้นจะอธิบายแต่ละโค้ดเรียกกลับ ได้แก่ สิ่งที่เกิดขึ้นภายในขณะที่โค้ดเรียกกลับทำงาน และสิ่งที่คุณต้องทำในระหว่างโค้ดเรียกกลับ
จากนั้นจะอธิบายความสัมพันธ์ระหว่างสถานะกิจกรรมและความเสี่ยงของกระบวนการที่จะถูกระบบปิด สุดท้ายนี้ จะกล่าวถึง หัวข้อต่างๆ ที่เกี่ยวข้องกับการเปลี่ยนสถานะของกิจกรรม
ดูข้อมูลเกี่ยวกับการจัดการวงจร รวมถึงคำแนะนำเกี่ยวกับแนวทางปฏิบัติแนะนำได้ที่วงจรใน Jetpack Compose และบันทึกสถานะ UI หากต้องการ ดูวิธีออกแบบแอปที่มีคุณภาพระดับโปรดักชันที่แข็งแกร่งโดยใช้กิจกรรมร่วมกับคอมโพเนนต์สถาปัตยกรรม โปรดดูคู่มือสถาปัตยกรรมแอป
แนวคิดวงจรของกิจกรรม
คลาส Activity มีชุด Callback หลัก 6 รายการ ได้แก่ onCreate, onStart, onResume, onPause, onStop และ onDestroy เพื่อช่วยในการไปยังส่วนต่างๆ ระหว่างช่วงต่างๆ ของวงจรกิจกรรม
ระบบจะเรียกใช้แต่ละแฮนเดิลนี้เมื่อกิจกรรมเข้าสู่สถานะใหม่
รูปที่ 1 แสดงภาพของกระบวนทัศน์นี้
เมื่อผู้ใช้เริ่มออกจากกิจกรรม ระบบจะเรียกใช้เมธอดเพื่อรื้อถอน กิจกรรม ในบางกรณี ระบบจะยกเลิกกิจกรรมเพียงบางส่วนและยังคง อยู่ในหน่วยความจำ เช่น เมื่อผู้ใช้เปลี่ยนไปใช้แอปอื่น ในกรณีเหล่านี้ กิจกรรมยังคงกลับมาอยู่เบื้องหน้าได้
หากผู้ใช้กลับมาที่กิจกรรม ระบบจะดำเนินการต่อจากจุดที่ผู้ใช้หยุดไว้ โดยมีข้อยกเว้นบางประการ แอปจะถูกจํากัดไม่ให้เริ่มกิจกรรมเมื่อทํางานในเบื้องหลัง
ความเป็นไปได้ที่ระบบจะสิ้นสุดกระบวนการที่ระบุพร้อมกับกิจกรรมในกระบวนการนั้นขึ้นอยู่กับสถานะของกิจกรรมในขณะนั้น ดูข้อมูลเพิ่มเติมเกี่ยวกับ ความสัมพันธ์ระหว่างสถานะและความเสี่ยงที่จะถูกนำออกจากหน่วยความจำได้ที่ส่วน เกี่ยวกับสถานะกิจกรรมและการนำออกจากหน่วยความจำ
คุณอาจไม่จำเป็นต้อง ใช้วิธีการวงจรทั้งหมด ทั้งนี้ขึ้นอยู่กับความซับซ้อนของกิจกรรม อย่างไรก็ตาม คุณควรทำความเข้าใจ แต่ละรายการและใช้รายการที่ทำให้แอปทำงานในแบบที่ผู้ใช้คาดหวัง
Compose และวงจร
ใน Compose ให้หลีกเลี่ยงการวางตรรกะทางธุรกิจหรือการตั้งค่า Observer ด้วยตนเองโดยตรง
ภายใน Callback ของกิจกรรม เช่น onStart หรือ onResume แต่ให้ใช้เอฟเฟกต์ที่รับรู้วงจรและ Observer ที่รับรู้สถานะซึ่งจะจัดแนวโดยอัตโนมัติ
ให้สอดคล้องกับการแสดง UI บนหน้าจอ
- คอลเล็กชันที่รับรู้ถึงวงจร: ใช้
collectAsStateWithLifecycleเพื่อ ใช้โฟลว์จากViewModelAPI นี้จะเริ่มรวบรวมโดยอัตโนมัติเมื่อ UI เข้าสู่สถานะ "เริ่ม" และจะหยุดเมื่อ UI เข้าสู่เบื้องหลัง ซึ่งจะช่วยป้องกันการใช้ทรัพยากรโดยไม่จำเป็น หลังจากรวบรวมโฟลว์เป็นสถานะแล้ว คุณจะใช้LifecycleEffectsเพื่อเรียกใช้โค้ดเมื่อเกิดเหตุการณ์ในวงจรได้ - ลำดับตรรกะ: การใช้ API เหล่านี้จะทำให้ UI ตอบสนองต่อสถานะวงจรขององค์ประกอบ อย่างเป็นธรรมชาติผ่านโครงสร้างการประกอบ ซึ่งช่วยให้มั่นใจได้ว่าตรรกะทางธุรกิจจะ ทำงานเฉพาะเมื่อผู้ใช้โต้ตอบกับคอมโพเนนต์อย่างแข็งขันเท่านั้น
ดูข้อมูลเพิ่มเติมเกี่ยวกับ Compose และวงจรได้ที่วงจรใน Jetpack Compose
Lifecycle Callback
ส่วนนี้ให้ข้อมูลแนวคิดและการติดตั้งใช้งานเกี่ยวกับ เมธอดเรียกกลับที่ใช้ในวงจรกิจกรรม
การดำเนินการบางอย่างอยู่ในเมธอดวงจรกิจกรรม อย่างไรก็ตาม ให้วางโค้ดที่ใช้การดำเนินการของคอมโพเนนต์ที่ขึ้นต่อกันในคอมโพเนนต์ แทนที่จะวางไว้ในเมธอดวงจรกิจกรรม หากต้องการดำเนินการนี้ คุณต้องทำให้คอมโพเนนต์ที่ขึ้นอยู่กับ รับรู้วงจรของคอมโพเนนต์ ดูวิธีทำให้คอมโพเนนต์ที่ขึ้นต่อกันรับรู้ถึงวงจร ได้ที่วงจรใน Jetpack Compose
onCreate
คุณต้องใช้การเรียกกลับนี้ ซึ่งจะเริ่มทำงานเมื่อระบบสร้างกิจกรรมเป็นครั้งแรก
เมื่อสร้างกิจกรรมแล้ว กิจกรรมจะเข้าสู่สถานะสร้างแล้ว ในเมธอด 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
เมื่อกิจกรรมเข้าสู่สถานะ "เริ่มแล้ว" ระบบจะเรียกใช้ onStart
การเรียกนี้จะทำให้กิจกรรมปรากฏต่อผู้ใช้ในขณะที่แอปเตรียมพร้อมสำหรับ
กิจกรรมที่จะเข้าสู่เบื้องหน้าและโต้ตอบได้ ตัวอย่างเช่น
เมธอดนี้คือที่ที่เริ่มต้นโค้ดที่ดูแล UI
เมื่อกิจกรรมเปลี่ยนไปเป็นสถานะ "เริ่มแล้ว" คอมโพเนนต์ที่รับรู้ถึงวงจรที่เชื่อมโยง
กับวงจรของกิจกรรมจะได้รับเหตุการณ์ ON_START
onStart เมธอดจะเสร็จสมบูรณ์อย่างรวดเร็ว และเช่นเดียวกับสถานะ Created กิจกรรมจะไม่อยู่ในสถานะ Started เมื่อการเรียกกลับนี้เสร็จสิ้น กิจกรรมจะเข้าสู่สถานะResumed และระบบจะเรียกใช้เมธอด onResume
onResume
เมื่อกิจกรรมเข้าสู่สถานะ "กลับมาทำงานต่อ" กิจกรรมจะมาอยู่เบื้องหน้า และระบบจะเรียกใช้แฮนเดิล onResume นี่คือสถานะที่แอป
โต้ตอบกับผู้ใช้ แอปจะอยู่ในสถานะนี้จนกว่าจะมีสิ่งใดเกิดขึ้นที่
ดึงโฟกัสออกจากแอป เช่น อุปกรณ์รับสายโทรศัพท์ ผู้ใช้ไปยังกิจกรรมอื่น หรือหน้าจออุปกรณ์ปิด
เมื่อกิจกรรมเปลี่ยนเป็นสถานะ "กลับมาทำงานต่อ" คอมโพเนนต์ที่รับรู้ถึงวงจรใดๆ ที่เชื่อมโยง
กับวงจรของกิจกรรมจะได้รับเหตุการณ์ ON_RESUME ซึ่งเป็นที่ที่คอมโพเนนต์วงจรสามารถเปิดใช้ฟังก์ชันการทำงานใดๆ ที่จำเป็นต้องทำงานขณะที่คอมโพเนนต์แสดงอยู่และอยู่ในเบื้องหน้า เช่น การเริ่มแสดงตัวอย่างกล้อง
เมื่อเกิดเหตุการณ์ที่ขัดจังหวะ กิจกรรมจะเข้าสู่สถานะหยุดชั่วคราวและ
ระบบจะเรียกใช้การเรียกกลับ 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
ข้อมูลโค้ดข้างต้นจะวางโค้ดการเริ่มต้นกล้องไว้ในคอมโพเนนต์ที่รับรู้ถึงวงจรของกิจกรรม
คุณสามารถใส่โค้ดนี้ลงในโค้ดเรียกกลับวงจรกิจกรรมโดยตรง เช่น onStart และ onStop แต่เราไม่แนะนำให้ทำเช่นนี้ การเพิ่มตรรกะนี้ลงในคอมโพเนนต์อิสระที่รับรู้ถึงวงจร
ช่วยให้คุณนําคอมโพเนนต์ไปใช้ซ้ำในกิจกรรมต่างๆ ได้โดยไม่ต้อง
ทําซ้ำโค้ด ดูวิธีสร้างคอมโพเนนต์ที่รับรู้ถึงวงจรได้ที่
วงจรใน Jetpack Compose
onPause
ระบบจะเรียกใช้เมธอดนี้เป็นสัญญาณแรกที่บ่งบอกว่าผู้ใช้กำลังจะออกจาก กิจกรรมของคุณ แม้ว่าไม่ได้หมายความว่าระบบจะทำลายกิจกรรมเสมอไป ซึ่งบ่งบอกว่ากิจกรรมไม่ได้อยู่ในเบื้องหน้าอีกต่อไป แต่ยังคง มองเห็นได้หากผู้ใช้อยู่ในโหมดหลายหน้าต่าง กิจกรรมอาจเข้าสู่สถานะนี้ได้จากหลายสาเหตุ ดังนี้
- เหตุการณ์ที่ขัดจังหวะการเรียกใช้แอปตามที่อธิบายไว้ในส่วนเกี่ยวกับ
การเรียกกลับ
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
}
...
}
ตัวอย่างนี้จะวางโค้ดการปล่อยกล้องหลังจากที่ ON_PAUSE ได้รับLifecycleObserver
onPauseจะสั้นมากและอาจไม่มีเวลาเพียงพอที่จะ
ดำเนินการบันทึก ด้วยเหตุนี้ อย่าใช้ onPause เพื่อบันทึก
ข้อมูลแอปพลิเคชันหรือข้อมูลผู้ใช้ ทำการเรียกเครือข่าย หรือดำเนินการธุรกรรมในฐานข้อมูล
งานดังกล่าวอาจไม่เสร็จสมบูรณ์ก่อนที่เมธอดจะเสร็จสมบูรณ์
แต่ให้ดำเนินการปิดระบบที่มีการโหลดสูงในช่วงonStopแทน ดูข้อมูลเพิ่มเติมเกี่ยวกับ
การดำเนินการที่เหมาะสมซึ่งควรทำในช่วงonStopได้ที่ส่วนถัดไป ดูข้อมูลเพิ่มเติมเกี่ยวกับการบันทึกข้อมูลได้ที่ส่วนเกี่ยวกับการบันทึก
และกู้คืนสถานะ
การทำตามonPauseวิธีนี้ไม่ได้หมายความว่ากิจกรรมจะออกจากสถานะ
หยุดชั่วคราว แต่กิจกรรมจะยังคงอยู่ในสถานะนี้จนกว่ากิจกรรมจะกลับมาทำงานต่อหรือผู้ใช้จะมองไม่เห็นกิจกรรมนั้นอีกเลย หากกิจกรรม
กลับมาทำงานต่อ ระบบจะเรียกใช้onResumeการเรียกกลับอีกครั้ง
หากกิจกรรมเปลี่ยนจากสถานะหยุดชั่วคราวเป็นสถานะกลับมาทำงานต่อ ระบบจะเก็บอินสแตนซ์ Activity ไว้ในหน่วยความจำและเรียกใช้อินสแตนซ์นั้นเมื่อระบบเรียกใช้ onResume ในกรณีนี้ คุณไม่จำเป็นต้องเริ่มต้นคอมโพเนนต์ที่สร้างขึ้นใหม่ในระหว่างเมธอดเรียกกลับใดๆ ที่นำไปสู่สถานะ "กลับมาทำงานต่อ" หากกิจกรรมมองไม่เห็นเลย ระบบจะเรียกใช้ onStop
onStop
เมื่อกิจกรรมไม่ปรากฏต่อผู้ใช้แล้ว กิจกรรมจะเข้าสู่สถานะหยุด
และระบบจะเรียกใช้การเรียกกลับ 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 จะเรียกใช้ก่อนที่กิจกรรมจะถูกทำลาย ระบบจะเรียกใช้แฮนเดิล
นี้ด้วยเหตุผล 2 ประการต่อไปนี้
- กิจกรรมกำลังจะสิ้นสุดลงเนื่องจากผู้ใช้ปิดกิจกรรมโดยสมบูรณ์ หรือเนื่องจากมีการเรียกใช้
finishในกิจกรรม - ระบบกำลังทำลายกิจกรรมชั่วคราวเนื่องจากการเปลี่ยนแปลงการกำหนดค่า เช่น การหมุนอุปกรณ์หรือการเข้าสู่โหมดหลายหน้าต่าง
เมื่อกิจกรรมเปลี่ยนไปอยู่ในสถานะ "ถูกทำลาย" คอมโพเนนต์ที่รับรู้ถึงวงจร
ซึ่งเชื่อมโยงกับวงจรของกิจกรรมจะได้รับเหตุการณ์ ON_DESTROY ซึ่งเป็นที่ที่คอมโพเนนต์วงจรของออบเจ็กต์สามารถล้างข้อมูลที่ต้องการก่อนที่Activityจะถูกทำลาย
แทนที่จะใส่ตรรกะใน Activity เพื่อพิจารณาว่าเหตุใดจึงมีการทำลาย
ให้ใช้ออบเจ็กต์ ViewModel เพื่อเก็บข้อมูลมุมมองที่เกี่ยวข้องสำหรับ
Activity หากมีการสร้าง Activity ใหม่เนื่องจากการเปลี่ยนแปลงการกำหนดค่า
ViewModel ก็ไม่ต้องดำเนินการใดๆ เนื่องจากระบบจะเก็บรักษาไว้และมอบให้แก่
อินสแตนซ์ Activity ถัดไป
หากไม่ได้สร้าง Activity ขึ้นมาใหม่ ระบบจะเรียกใช้เมธอด onCleared ของ ViewModel ซึ่งจะล้างข้อมูลที่จำเป็นก่อนที่จะถูกทำลาย คุณแยกความแตกต่างระหว่าง 2 สถานการณ์นี้ได้ด้วยวิธี
isFinishing
หากกิจกรรมกำลังจะสิ้นสุด onDestroy คือ Lifecycle Callback ครั้งสุดท้ายที่กิจกรรมได้รับ หากมีการเรียก onDestroy อันเป็นผลมาจากการเปลี่ยนแปลงการกำหนดค่า
ระบบจะสร้างอินสแตนซ์กิจกรรมใหม่ทันที แล้วเรียก onCreate ในอินสแตนซ์ใหม่นั้นในการกำหนดค่าใหม่
การเรียกกลับ onDestroy จะปล่อยทรัพยากรทั้งหมดที่การเรียกกลับก่อนหน้าไม่ได้ปล่อย เช่น 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 จะจัดการการเรียงอันดับไปยังแพ็กเกจสถานะอินสแตนซ์เบื้องหลัง
var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) { mutableStateOf( TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length)) ) }
หากต้องการบันทึกข้อมูลแบบถาวร เช่น ค่ากำหนดของผู้ใช้หรือข้อมูลสำหรับฐานข้อมูล ให้ใช้โอกาสที่เหมาะสมเมื่อกิจกรรมของคุณอยู่เบื้องหน้า หากไม่มีโอกาสดังกล่าว ให้บันทึกข้อมูลที่คงอยู่ระหว่างเมธอด onStop
คืนค่าสถานะ UI ของกิจกรรมโดยใช้สถานะอินสแตนซ์ที่บันทึกไว้
เมื่อสร้างกิจกรรมขึ้นใหม่หลังจากที่ถูกทำลายไปก่อนหน้านี้ การคืนค่าสถานะจะเกิดขึ้นโดยอัตโนมัติ เมื่อใช้ rememberSaveable คุณไม่จำเป็นต้อง
เขียนตรรกะการคืนค่าที่ชัดเจน ตรวจสอบแพ็กเกจที่เป็น Null หรือลบล้าง
การเรียกกลับของกิจกรรม โค้ดที่เริ่มต้นและบันทึกสถานะจะกู้คืนสถานะอย่างราบรื่นเมื่อกิจกรรมกลับมาด้วย
var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) { mutableStateOf( TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length)) ) }
กิจกรรมและการนำทาง
แอปมักจะเปลี่ยนหน้าจอหลายครั้งในระหว่างอายุการใช้งาน
เช่น เมื่อผู้ใช้แตะปุ่มย้อนกลับของอุปกรณ์หรือเลือกปลายทางใหม่ โดยปกติแล้ว แอป Android สมัยใหม่จะใช้สถาปัตยกรรมแบบกิจกรรมเดียว
แทนที่จะเริ่ม Activity ใหม่สำหรับทุกหน้าจอ แอปจะโฮสต์ Activity เดียวและใช้คอมโพเนนต์ Navigation เพื่อสลับหน้าจอที่ใช้ Composable ภายในกิจกรรมนั้น
ดูวิธีใช้การนำทางสมัยใหม่ที่ใช้ 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 API ผลลัพธ์ที่ทันสมัยแทนการเรียกกลับ startActivityForResult ที่เลิกใช้งานแล้ว
การประสานงานกิจกรรม
เมื่อกิจกรรมหนึ่งเริ่มอีกกิจกรรมหนึ่ง ทั้ง 2 กิจกรรมจะเปลี่ยนวงจร กิจกรรมแรกจะหยุดทำงานและเข้าสู่สถานะหยุดชั่วคราวหรือหยุด ขณะที่ ระบบจะสร้างกิจกรรมอื่น ในกรณีที่กิจกรรมเหล่านี้แชร์ข้อมูลที่บันทึกลงในดิสก์ หรือที่อื่นๆ คุณควรทราบว่าระบบจะไม่หยุดกิจกรรมแรก โดยสมบูรณ์ก่อนที่จะสร้างกิจกรรมที่สอง แต่กระบวนการ เริ่มรายการที่ 2 จะทับซ้อนกับกระบวนการหยุดรายการแรก
ลำดับของโค้ดเรียกกลับของวงจรการทำงานได้รับการกำหนดไว้อย่างดี โดยเฉพาะอย่างยิ่งเมื่อกิจกรรม 2 รายการอยู่ในกระบวนการเดียวกัน ซึ่งก็คือแอปเดียวกัน และกิจกรรมหนึ่งเริ่มอีกกิจกรรมหนึ่ง ต่อไปนี้คือลำดับการทำงานที่เกิดขึ้นเมื่อกิจกรรม A เริ่มกิจกรรม B
- เมธอด
onPauseของกิจกรรม A จะทํางาน - เมธอด
onCreate,onStartและonResumeของกิจกรรม B จะทำงานตามลำดับ ตอนนี้กิจกรรม B มีโฟกัสของผู้ใช้แล้ว - หากกิจกรรม A ไม่ปรากฏบนหน้าจออีกต่อไป ระบบจะเรียกใช้เมธอด
onStopของกิจกรรม
ลำดับการเรียกกลับของวงจรชีวิตนี้ช่วยให้คุณจัดการการเปลี่ยนข้อมูลจากกิจกรรมหนึ่งไปยังอีกกิจกรรมหนึ่งได้
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับวงจรกิจกรรมได้จากแหล่งข้อมูลเพิ่มเติมต่อไปนี้