Ο κύκλος ζωής μιας εφαρμογής για κινητά καθορίζει πώς συμπεριφέρεται κατά την εκκίνηση, την ελαχιστοποίηση, την επιστροφή από το παρασκήνιο και το κλείσιμο. Σε αυτό το άρθρο, θα εξετάσουμε τα 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 μπορεί να αποτελείται από πολλά Activities, το καθένα με τον δικό του κύκλο.
Η σύγχρονη προσέγγιση στο 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 αλλά προσθέτει νέες μεθόδους. Τα Fragments μπορούν να προστεθούν, να αντικατασταθούν, να αφαιρεθούν χωρίς να καταστρέψουν το 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 διαχειρίζεται τον κύκλο ζωής των Views μέσω δομών View. Αντί για μεθόδους callback, το SwiftUI χρησιμοποιεί τροποποιητές onAppear και onDisappear. Για καθολικές καταστάσεις εφαρμογής, χρησιμοποιείται το App Lifecycle μέσω των πρωτοκόλλων App και Scene. Το SwiftUI διαχειρίζεται αυτόματα τη δημιουργία και καταστροφή των Views βάσει κατάστασης, απλοποιώντας την ανάπτυξη αλλά απαιτώντας κατανόηση της ταυτότητας και της διάρκειας ζωής του 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, εγγυώμενο αυτόματη ακύρωση coroutines όταν το 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. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.