วงจรชีวิตของแอปมือถือกำหนดว่าแอปทำงานอย่างไรเมื่อเปิดใช้งาน ย่อเล็กสุด กลับจากพื้นหลัง และปิด ในบทความนี้ เราจะกล่าวถึง App Lifecycle (iOS), Activity Lifecycle (Android), Fragment Lifecycle, ViewController Lifecycle และ LifecycleOwner การทำความเข้าใจกระบวนการเหล่านี้มีความสำคัญอย่างยิ่งในการป้องกันการรั่วไหลของหน่วยความจำ การสูญเสียข้อมูล และการทำงานที่ไม่ถูกต้องของแอป รายละเอียดเพิ่มเติมใน เอกสารทางการของ Android Activity Lifecycle
ประเด็นสำคัญ
ก่อนที่จะเจาะลึกวงจรชีวิตของแต่ละหน้าจอ สิ่งสำคัญคือต้องเข้าใจวงจรชีวิตของทั้งแอปพลิเคชัน ใน iOS แอปต้องผ่าน ห้าสถานะ: Not Running (ไม่ทำงาน), Inactive (ในพื้นหลัง ไม่รับเหตุการณ์), Active (ทำงานอยู่), Background (ในพื้นหลัง กำลังรันโค้ด) และ Suspended (ในพื้นหลัง โค้ดถูกพัก) สถานะเหล่านี้ถูกจัดการใน AppDelegate ผ่านเมธอด applicationDidFinishLaunching, applicationDidBecomeActive, applicationWillResignActive, applicationDidEnterBackground และ applicationWillTerminate
ใน Android สิ่งที่เทียบเท่าคือ Application Lifecycle ซึ่งติดตามผ่านอินเทอร์เฟซ Application.ActivityLifecycleCallbacks อย่างไรก็ตาม Android ให้ความสำคัญกับวงจรชีวิตของ Activity — หน้าจอแอปแต่ละหน้า เนื่องจากแอป Android สามารถประกอบด้วยหลาย Activity แต่ละอันมีวงจรของตัวเอง
แนวทางสมัยใหม่ใน Android คือการใช้ ProcessLifecycleOwner จากไลบรารี lifecycle-process ซึ่งช่วยให้ติดตามสถานะของทั้งกระบวนการโดยไม่ผูกกับ Activity เฉพาะ ใน iOS ใช้ UISceneDelegate (ตั้งแต่ iOS 13) หรือ AppDelegate เพื่อติดตามสถานะแอป SceneDelegate จัดการหลายหน้าต่าง (multiwindow) บน iPad การทำความเข้าใจ App Lifecycle มีความสำคัญเป็นพิเศษสำหรับ IT Sectr เมื่อพัฒนาแอปที่มีการซิงค์พื้นหลัง การสตรีม และการโทร VoIP
Activity เป็นคอมโพเนนต์พื้นฐานของแอป Android แทนหนึ่งหน้าจอ Activity มีวงจรชีวิตที่กำหนดไว้อย่างชัดเจนซึ่งจัดการโดยระบบปฏิบัติการเพื่อตอบสนองต่อการกระทำของผู้ใช้และเหตุการณ์ของระบบ (การหมุนหน้าจอ สายเรียกเข้า หน่วยความจำไม่เพียงพอ)
| เมธอด | คำอธิบาย | สิ่งที่ต้องทำ |
|---|---|---|
| onCreate | เรียกหนึ่งครั้งเมื่อสร้าง Activity | เริ่มต้น UI, findViewById, ตั้งค่า ViewModel |
| onStart | Activity มองเห็นได้ | เริ่มแอนิเมชัน, ลงทะเบียน BroadCastReceiver |
| onResume | Activity ได้รับโฟกัสอินพุต | เริ่มกล้อง, เซนเซอร์, แอนิเมชัน |
| onPause | Activity สูญเสียโฟกัส (มองเห็นบางส่วน) | บันทึกแบบร่าง, หยุดแอนิเมชัน |
| onStop | Activity ไม่มองเห็น | ปล่อยทรัพยากร, หยุดอัปเดต |
| onDestroy | Activity ถูกทำลาย | ล้างการอ้างอิงทั้งหมด, ยกเลิกการสมัคร LiveData |
| onRestart | เรียกก่อน onStart หลังจาก onStop | เริ่มต้นใหม่ |
สำคัญ: onSaveInstanceState ถูกเรียกก่อน onStop เพื่อบันทึกสถานะชั่วคราว การกู้คืนเกิดขึ้นใน onCreate ผ่าน Bundle savedInstanceState หรือผ่าน SavedStateHandle ใน ViewModel หากไม่จัดการวงจรชีวิตอย่างถูกต้อง แอปจะสูญเสียข้อมูลที่ไม่ได้บันทึกทั้งหมดเมื่อหมุนหน้าจอ
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("draft", draftText)
}
override fun onDestroy() {
super.onDestroy()
// Отписка от всех подписок
}
}
ใน Jetpack Compose วงจรชีวิตของ Activity ยังคงไม่เปลี่ยนแปลง แต่ Compose มีเครื่องมือเพิ่มเติม: การประกอบที่รับรู้วงจรชีวิต ผ่าน LifecycleOwner, เอฟเฟกต์ LifecycleEventEffect และ DisposableEffect สำหรับการล้างทรัพยากรอัตโนมัติเมื่อถูกทำลาย
Fragment ใน Android อาศัยอยู่ภายใน Activity และมีวงจรชีวิตของตัวเอง ซึ่งซ้อนทับกับ Activity บางส่วนแต่เพิ่มเมธอดใหม่ สามารถเพิ่ม เปลี่ยน ลบ Fragment โดยไม่ต้องทำลาย Activity ทำให้ยืดหยุ่นมากขึ้นแต่ซับซ้อนมากขึ้น
เมธอดหลักของ Fragment Lifecycle: onAttach — Fragment แนบกับ Activity (เรียกครั้งแรก); onCreate — เริ่มต้นข้อมูล; onCreateView — สร้าง View; onViewCreated — View ถูกสร้างแล้ว สามารถกำหนดค่า UI ได้; onStart — Fragment มองเห็น; onResume — Fragment มีโฟกัส; onPause — Fragment สูญเสียโฟกัส; onStop — Fragment ไม่มองเห็น; onDestroyView — View ถูกทำลาย; onDestroy — Fragment ถูกทำลาย; onDetach — Fragment ถูกถอดจาก Activity
ความแตกต่างหลักจาก Activity: onCreateView และ onDestroyView สามารถเรียกหลายครั้ง (เช่น เมื่อเปลี่ยน TabLayout) ในขณะที่ onCreate เรียกครั้งเดียว ดังนั้นการเริ่มต้น View ควรทำใน onViewCreated ไม่ใช่ใน onCreateView ทรัพยากรที่เกี่ยวข้องกับ View (เช่น อะแดปเตอร์ RecyclerView) ควรล้างใน onDestroyView
UIViewController เป็นคลาสพื้นฐานสำหรับจัดการหน้าจอใน iOS วงจรชีวิตของมันประกอบด้วยลำดับเมธอดที่ UIKit เรียกโดยอัตโนมัติ การทำความเข้าใจวงจรนี้มีความสำคัญอย่างยิ่งสำหรับการเริ่มต้น UI การจัดการข้อมูล และหน่วยความจำที่ถูกต้อง
| เมธอด | เมื่อเรียก | การใช้งานทั่วไป |
|---|---|---|
| loadView | เมื่อ View Controller โหลดลำดับชั้น View | เริ่มต้นแบบกำหนดเองโดยไม่มี storyboard |
| viewDidLoad | หลังจาก View โหลดในหน่วยความจำ (ครั้งเดียว) | ตั้งค่า UI, โหลดข้อมูลเริ่มต้น |
| viewWillAppear | ก่อน View ปรากฏบนหน้าจอ | อัปเดตข้อมูล, สมัครรับการแจ้งเตือน |
| viewDidAppear | หลังจาก View ปรากฏบนหน้าจอ | เริ่มแอนิเมชัน, เริ่มติดตามแอนิเมชัน |
| viewWillDisappear | ก่อน View หายไปจากหน้าจอ | บันทึกสถานะ, ยกเลิกการสมัครรับการแจ้งเตือน |
| viewDidDisappear | หลังจาก View หายไปจากหน้าจอ | หยุดแอนิเมชัน, ปล่อยทรัพยากร |
| dealloc | เมื่อ View Controller ถูกทำลาย | ปล่อยทรัพยากรทั้งหมด |
สำคัญ: viewDidLoad ถูกเรียกเพียงครั้งเดียวในอายุของ View Controller หากต้องการอัปเดตข้อมูลทุกครั้งที่ปรากฏ ให้ใช้ viewWillAppear ถ้าคุณสมัครรับ NotificationCenter ใน viewWillAppear อย่าลืมยกเลิกการสมัครใน viewDidDisappear เพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำ
SwiftUI จัดการวงจรชีวิตของ View ผ่านโครงสร้าง View แทนที่จะใช้เมธอด callback SwiftUI ใช้ตัวปรับแต่ง onAppear และ onDisappear สำหรับสถานะแอปทั่วโลก จะใช้ App Lifecycle ผ่านโปรโตคอล App และ Scene SwiftUI จัดการการสร้างและทำลาย View โดยอัตโนมัติตามสถานะ ซึ่งทำให้การพัฒนาง่ายขึ้น แต่ต้องเข้าใจ identity และอายุของ View
struct ContentView: View {
var body: some View {
Text("Hello")
.onAppear {
print("View появилась")
}
.onDisappear {
print("View исчезла")
}
}
}
LifecycleOwner เป็นอินเทอร์เฟซจาก Android Architecture Components ที่ทำเครื่องหมายอ็อบเจ็กต์ที่มีวงจรชีวิต (Activity, Fragment) LifecycleObserver เป็นอินเทอร์เฟซที่อนุญาตให้อ็อบเจ็กต์สมัครรับเหตุการณ์ของ LifecycleOwner เมื่อรวมกันแล้ว สิ่งเหล่านี้เป็นพื้นฐานของการจัดการวงจรชีวิตแบบรีแอกทีฟในการพัฒนา Android สมัยใหม่
แทนที่จะเรียกเมธอดอย่างชัดเจนใน onStart/onStop แนะนำให้ใช้ DefaultLifecycleObserver (แทนที่ LifecycleObserver เดิมด้วยคำอธิบายประกอบ @OnLifecycleEvent) นี่เป็นแนวทางที่ Google ส่งเสริมสำหรับ ViewModel และคอมโพเนนต์อื่น ๆ ที่ต้องตอบสนองต่อวงจรชีวิตโดยไม่ต้องมีการอ้างอิงโดยตรงไปยัง Activity หรือ Fragment
class MyObserver : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
// Подписка на обновления
}
override fun onStop(owner: LifecycleOwner) {
// Отписка
}
}
ที่ IT Sectr เราใช้ LifecycleOwner ในทุกโปรเจกต์ Android ViewModel สมัครรับ LifecycleOwner ของ Activity ผ่าน viewModelScope และ lifecycleScope ซึ่งรับประกันการยกเลิก coroutine อัตโนมัติเมื่อ Activity ถูกทำลาย สิ่งนี้ป้องกันการรั่วไหลของหน่วยความจำและทำให้โค้ดสะอาดและปลอดภัยยิ่งขึ้น
คำถามที่พบบ่อย
Activity ผ่านหกสถานะ: Created (onCreate), Started (onStart), Resumed (onResume), Paused (onPause), Stopped (onStop), Destroyed (onDestroy)
ลำดับ: loadView → viewDidLoad → viewWillAppear → viewDidAppear → viewWillDisappear → viewDidDisappear viewDidLoad ถูกเรียกหนึ่งครั้ง
LifecycleOwner เป็นคอมโพเนนต์ของ Android Architecture Components ที่เป็นเจ้าของวงจรชีวิตของ Activity หรือ Fragment อนุญาตให้สมัครรับเหตุการณ์ผ่าน LifecycleObserver
แอป iOS ผ่านห้าสถานะ: Not Running, Inactive, Active, Background, Suspended การเปลี่ยนสถานะจัดการผ่าน UIApplicationDelegate
Saved State เป็นกลไกของ Android เพื่อรักษาสถานะ Activity/Fragment เมื่อหมุนหน้าจอหรือสร้างกระบวนการใหม่ ใช้ onSaveInstanceState และ SavedStateHandle
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ