เมื่อผู้ใช้ไปยังส่วนต่างๆ ของแอป ออกจากแอป และกลับมาที่แอป อินสแตนซ์ Activity ในแอปจะเปลี่ยนผ่านสถานะต่างๆ ในวงจรของอินสแตนซ์
คลาส Activity มี Callback จำนวนมากที่ช่วยให้กิจกรรมทราบเมื่อสถานะมีการเปลี่ยนแปลง หรือเมื่อระบบกำลังสร้าง หยุด หรือกลับมาทำกิจกรรมต่อ หรือทำลายกระบวนการที่กิจกรรมนั้นอยู่
ภายในเมธอด Lifecycle Callback คุณสามารถประกาศลักษณะการทำงานของกิจกรรมเมื่อผู้ใช้ออกจากกิจกรรมและกลับเข้ามาใหม่ได้ ตัวอย่างเช่น หากคุณกำลังสร้างวิดีโอเพลเยอร์สตรีมมิง คุณอาจหยุดวิดีโอชั่วคราวและสิ้นสุดการเชื่อมต่อเครือข่ายเมื่อผู้ใช้เปลี่ยนไปใช้แอปอื่น เมื่อผู้ใช้กลับมา คุณสามารถเชื่อมต่อเครือข่ายอีกครั้งและให้ผู้ใช้เล่นวิดีโอต่อจากจุดเดิมได้
Callback แต่ละรายการช่วยให้คุณทำงานเฉพาะที่เหมาะสมกับการเปลี่ยนแปลงสถานะที่กำหนดได้ การทำงานที่เหมาะสมในเวลาที่เหมาะสมและการจัดการการเปลี่ยนผ่านอย่างเหมาะสมจะทำให้แอปของคุณมีประสิทธิภาพและเสถียรมากขึ้น ตัวอย่างเช่น การใช้ Lifecycle Callback ที่ดีจะช่วยให้แอปหลีกเลี่ยงสิ่งต่อไปนี้ได้
- ขัดข้องหากผู้ใช้รับสายโทรศัพท์หรือสลับไปใช้แอปอื่นขณะใช้แอปของคุณ
- ใช้ทรัพยากรระบบที่มีค่าเมื่อผู้ใช้ไม่ได้ใช้งานอยู่
- การสูญเสียความคืบหน้าของผู้ใช้หากผู้ใช้ออกจากแอปและกลับมาในภายหลัง
- ขัดข้องหรือสูญเสียความคืบหน้าของผู้ใช้เมื่อหน้าจอหมุนระหว่างการวางแนวแนวนอนและแนวตั้ง
เอกสารนี้จะอธิบายวงจรกิจกรรมโดยละเอียด เอกสารเริ่มต้นด้วยการอธิบายกระบวนทัศน์ของวงจรการใช้งาน จากนั้นจะอธิบาย Callback แต่ละรายการว่าเกิดอะไรขึ้นภายในขณะที่ Callback ทำงาน และสิ่งที่คุณต้องทำในระหว่างนั้น
จากนั้นจะแนะนำความสัมพันธ์ระหว่างสถานะกิจกรรมกับความเสี่ยงที่กระบวนการจะถูกระบบปิดการทำงานโดยสังเขป สุดท้ายนี้ เราจะพูดถึงหัวข้อต่างๆ ที่เกี่ยวข้องกับการเปลี่ยนสถานะของกิจกรรม
ดูข้อมูลเกี่ยวกับการจัดการวงจร รวมถึงคำแนะนำเกี่ยวกับแนวทางปฏิบัติแนะนำได้ที่วงจรใน Jetpack Compose และบันทึกสถานะ UI หากต้องการดูวิธีออกแบบแอปที่มีประสิทธิภาพและมีคุณภาพระดับเวอร์ชันที่ใช้งานจริงโดยใช้กิจกรรมร่วมกับคอมโพเนนต์สถาปัตยกรรม โปรดดูคู่มือสถาปัตยกรรมแอป
แนวคิดเกี่ยวกับวงจรกิจกรรม
หากต้องการไปยังส่วนต่างๆ ของการเปลี่ยนผ่านระหว่างระยะต่างๆ ของวงจรกิจกรรม คลาส Activity จะมีชุด Callback หลัก 6 ชุด ได้แก่ onCreate, onStart, onResume, onPause, onStop และ onDestroy ระบบจะเรียกใช้ Callback แต่ละรายการเหล่านี้เมื่อกิจกรรมเข้าสู่สถานะใหม่
รูปที่ 1 แสดงภาพของกระบวนทัศน์นี้
เมื่อผู้ใช้เริ่มออกจากกิจกรรม ระบบจะเรียกใช้เมธอดเพื่อแยกส่วนกิจกรรม ในบางกรณี ระบบจะรื้อถอนกิจกรรมเพียงบางส่วนและยังคงอยู่ในหน่วยความจำ เช่น เมื่อผู้ใช้เปลี่ยนไปใช้แอปอื่น ในกรณีเหล่านี้ กิจกรรมยังคงกลับมาทำงานในเบื้องหน้าได้
หากผู้ใช้กลับมาที่กิจกรรม กิจกรรมจะกลับมาทำงานต่อจากจุดที่ผู้ใช้หยุดไป แอปจะถูกจำกัดไม่ให้เริ่มกิจกรรมเมื่อทำงานอยู่เบื้องหลัง โดยมีข้อยกเว้นบางประการ
แนวโน้มที่ระบบจะหยุดกระบวนการหนึ่งๆ พร้อมกับกิจกรรมในกระบวนการนั้นขึ้นอยู่กับสถานะของกิจกรรมในขณะนั้น ดูข้อมูลเพิ่มเติมเกี่ยวกับความสัมพันธ์ระหว่างสถานะและความเสี่ยงต่อการถูกนำออกจากหน่วยความจำได้ที่ส่วนสถานะกิจกรรมและการนำออกจากหน่วยความจำ
คุณอาจไม่จำเป็นต้องใช้เมธอดวงจรทั้งหมด ทั้งนี้ขึ้นอยู่กับความซับซ้อนของกิจกรรม อย่างไรก็ตาม คุณควรทำความเข้าใจแต่ละสิทธิ์และใช้สิทธิ์ที่ทำให้แอปทำงานในลักษณะที่ผู้ใช้คาดหวัง
Compose และวงจร
ใน Compose ให้หลีกเลี่ยงการวางตรรกะทางธุรกิจหรือการตั้งค่าผู้สังเกตการณ์ด้วยตนเองโดยตรงภายใน Callback ของกิจกรรม เช่น onStart หรือ onResume แต่ให้ใช้เอฟเฟกต์ที่รับรู้วงจรชีวิตและผู้สังเกตการณ์ที่รับรู้สถานะซึ่งจะปรับให้สอดคล้องกับการแสดงผลของ UI บนหน้าจอโดยอัตโนมัติแทน
- คอลเล็กชันที่รับรู้ถึงวงจร: ใช้
collectAsStateWithLifecycleเพื่อใช้โฟลว์จากViewModelAPI นี้จะเริ่มรวบรวมข้อมูลโดยอัตโนมัติเมื่อ 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 นี้ด้วยเหตุผลข้อใดข้อหนึ่งต่อไปนี้
- กิจกรรมกำลังจะสิ้นสุดลงเนื่องจากผู้ใช้ปิดกิจกรรมโดยสมบูรณ์หรือเนื่องจากมีการเรียกใช้
finishในกิจกรรม - ระบบกำลังทำลายกิจกรรมชั่วคราวเนื่องจากมีการเปลี่ยนแปลงการกำหนดค่า เช่น การหมุนอุปกรณ์หรือการเข้าสู่โหมดหลายหน้าต่าง
เมื่อกิจกรรมเปลี่ยนเป็นสถานะถูกทำลาย คอมโพเนนต์ที่รับรู้วงจรซึ่งเชื่อมโยงกับวงจรของกิจกรรมจะได้รับเหตุการณ์ 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 รายการอยู่ในกระบวนการเดียวกัน หรือกล่าวคืออยู่ในแอปเดียวกัน และกิจกรรมหนึ่งกำลังเริ่มอีกกิจกรรมหนึ่ง ลำดับการดำเนินการที่เกิดขึ้นเมื่อกิจกรรม ก เริ่มกิจกรรม ข มีดังนี้
- เมธอด
onPauseของกิจกรรม A ทำงาน - เมธอด
onCreate,onStartและonResumeของกิจกรรม B จะทำงานตามลำดับ ตอนนี้กิจกรรม B มีโฟกัสของผู้ใช้แล้ว - หากกิจกรรม A ไม่ปรากฏบนหน้าจออีกต่อไป เมธอด
onStopของกิจกรรมจะทำงาน
ลำดับของ Lifecycle Callback นี้ช่วยให้คุณจัดการการเปลี่ยนผ่านของข้อมูลจากกิจกรรมหนึ่งไปยังอีกกิจกรรมหนึ่งได้
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับวงจรกิจกรรมได้ที่แหล่งข้อมูลเพิ่มเติมต่อไปนี้