Active: τι είναι, κατάσταση Active στον κύκλο ζωής iOS

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-03-03 Χρόνος ανάγνωσης: 10 λεπ

Active — η ενεργή κατάσταση του κύκλου ζωής μιας εφαρμογής iOS, στην οποία βρίσκεται στο προσκήνιο, λαμβάνει γεγονότα αφής και αλληλεπιδρά με τον χρήστη. Αναλύουμε πώς λειτουργεί η κατάσταση Active, ποιες μέθοδοι του UIApplicationDelegate είναι υπεύθυνες για αυτήν και πώς να χειριζόμαστε σωστά τις μεταβάσεις μεταξύ Active και Inactive στη Swift.

Κύρια Σημεία

  • Active — εφαρμογή στο προσκήνιο, το UIResponder λαμβάνει γεγονότα αφής, η εφαρμογή είναι πλήρως διαδραστική
  • applicationDidBecomeActive — η κύρια μέθοδος που σηματοδοτεί τη μετάβαση σε Active στο iOS
  • ScenePhase.active — το αντίστοιχο για SwiftUI, παρακολουθείται μέσω Environment values
  • Επιστροφή από Inactive — μετά από κλήση, ειδοποίηση ή Control Center η εφαρμογή γίνεται ξανά Active
  • Πόροι — στην κατάσταση Active η εφαρμογή έχει την υψηλότερη προτεραιότητα μνήμης και επεξεργαστή

Active: τι είδους κατάσταση είναι

Active — κατάσταση του κύκλου ζωής μιας φορητής εφαρμογής, στην οποία βρίσκεται στο προσκήνιο, εμφανίζεται στην οθόνη της συσκευής και αλληλεπιδρά ενεργά με τον χρήστη. Σε αυτή την κατάσταση, η εφαρμογή λαμβάνει όλα τα γεγονότα αφής, τα πατήματα πλήκτρων, τα δεδομένα από το επιταχυνσιόμετρο και το γυροσκόπιο, καθώς και έχει πλήρη πρόσβαση στον επεξεργαστή γραφικών για την απόδοση της διεπαφής.

Στο iOS, η κατάσταση Active αποτελεί μέρος του μοντέλου πέντε καταστάσεων του κύκλου ζωής: Not Running → Inactive → Active → Inactive → Background → Suspended → Not Running. Στο Android, το αντίστοιχο είναι η κατάσταση του Activity μετά την κλήση onResume, όταν το Activity βρίσκεται στην κορυφή της στοίβας και δέχεται είσοδο χρήστη. Το Active είναι η μοναδική κατάσταση στην οποία το UI είναι πλήρως διαδραστικό και αντιδρά σε χειρονομίες, κύλιση, κλικ και κινούμενα σχέδια.

Το σύστημα παρέχει στην εφαρμογή σε Active μέγιστη προτεραιότητα επεξεργαστή και RAM. Αυτό σημαίνει ότι το σύστημα δεν θα τερματίσει μια τέτοια εφαρμογή σε περίπτωση έλλειψης πόρων — πρώτα θα εκφορτωθούν οι διεργασίες παρασκηνίου και οι ανασταλείσες. Ωστόσο, η εφαρμογή πρέπει να χρησιμοποιεί αποτελεσματικά τους πόρους για να μην εξαντλεί την μπαταρία και να προκαλεί throttling CPU.

Για τον χρήστη, το Active είναι η κανονική κατάσταση λειτουργίας με την εφαρμογή. Ο χρήστης βλέπει τη διεπαφή, μπορεί να πατάει κουμπιά, να συμπληρώνει φόρμες, να κυλάει στην τροφοδοσία. Οποιαδήποτε διακοπή αυτής της κατάστασης (κλήση, ειδοποίηση, σύρσιμο προς τα πάνω για Control Center) μεταφέρει την εφαρμογή σε Inactive, μετά από το οποίο μπορεί να επιστρέψει σε Active ή να πάει σε Background.

Πώς καθορίζει το σύστημα ότι η εφαρμογή είναι Active

Το iOS χρησιμοποιεί το UIApplicationMain για τη διαχείριση κατάστασης. Κατά τη μετάβαση σε Active, το σύστημα καλεί το applicationDidBecomeActive. Για το SwiftUI, ο ανάλογος μηχανισμός είναι η παρακολούθηση του scenePhase μέσω του Environment. Το Android χρησιμοποιεί το onResume ως δείκτη δραστηριότητας του Activity στο προσκήνιο. Και οι δύο προσεγγίσεις εγγυώνται ότι η εφαρμογή λαμβάνει ειδοποίηση για την αλλαγή κατάστασης και μπορεί να προσαρμόσει τη συμπεριφορά της.

ΠλατφόρμαΜέθοδος/γεγονόςSwift (UIKit)SwiftUIAndroid (Kotlin)
iOSΜετάβαση σε ActiveapplicationDidBecomeActivescenePhase == .active
iOSΈξοδος από ActiveapplicationWillResignActivescenePhase == .inactive
AndroidΜετάβαση σε ActiveonResume()
AndroidΈξοδος από ActiveonPause()

Active στο iOS: Swift, UIKit και SwiftUI

Στο iOS, η κατάσταση Active χειρίζεται μέσω του UIApplicationDelegate. Η κύρια μέθοδος — applicationDidBecomeActive(_:). Καλείται κατά την πρώτη εκκίνηση της εφαρμογής και κατά την επιστροφή από Inactive. Αυτή η μέθοδος είναι το ιδανικό μέρος για την επανάληψη εργασιών που είχαν ανασταλεί κατά τη μετάβαση σε Inactive: εκκίνηση κινούμενων σχεδίων, επανάληψη χρονοδιακοπτών, επανεκκίνηση αισθητήρων, έλεγχος ενημερώσεων δεδομένων στον διακομιστή.

UIKit: AppDelegate και SceneDelegate

Από το iOS 13, η Apple εισήγαγε το UISceneDelegate για υποστήριξη πολλαπλών παραθύρων σε iPad. Σε αυτή την περίπτωση, το applicationDidBecomeActive αντικαθίσταται από το sceneDidBecomeActive για κάθε σκηνή. Οι εφαρμογές που υποστηρίζουν μόνο μία οθόνη μπορούν να συνεχίσουν να χρησιμοποιούν το UIApplicationDelegate. Και οι δύο προσεγγίσεις καλούνται τη στιγμή που η εφαρμογή ή η σκηνή γίνεται ενεργή.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Η εφαρμογή έγινε ενεργή — συνεχίζουμε τις εργασίες
    func applicationDidBecomeActive(_ application: UIApplication) {
        resumeAnimations()
        restartTimers()
        refreshDataIfNeeded()
        startObservingSensors()
    }

    // Η εφαρμογή χάνει δραστηριότητα — αναστέλλουμε
    func applicationWillResignActive(_ application: UIApplication) {
        pauseAnimations()
        stopTimers()
        saveDraftData()
    }

    private func resumeAnimations() {
        UIView.animate(withDuration: 0.3) {
            // Συνέχιση κινούμενων σχεδίων UI
        }
    }

    private func refreshDataIfNeeded() {
        let lastRefresh = UserDefaults.standard.object(forKey: "lastRefresh") as? Date ?? .distantPast
        if Date().timeIntervalSince(lastRefresh) > 300 {
            fetchDataFromServer()
        }
    }
}

Ο κώδικας δείχνει τον σωστό χειρισμό του Active στο UIKit. Το applicationDidBecomeActive συνεχίζει τα κινούμενα σχέδια, τους χρονοδιακόπτες και ελέγχει εάν απαιτείται ενημέρωση δεδομένων. Το applicationWillResignActive αναστέλλει οτιδήποτε μπορεί να καταναλώνει πόρους και αποθηκεύει πρόχειρα. Ένα τέτοιο ζεύγος μεθόδων εγγυάται ότι η εφαρμογή αντιδρά σωστά στην αλλαγή κατάστασης.

SwiftUI: scenePhase

Στο SwiftUI δεν υπάρχει AppDelegate — η διαχείριση κατάστασης γίνεται μέσω του Environment<ScenePhase>. Η τιμή .active ορίζεται όταν η σκηνή βρίσκεται στο προσκήνιο και είναι διαδραστική. Το SwiftUI επανεκκινεί αυτόματα τα κινούμενα σχέδια και τις ενημερώσεις κατά την επιστροφή σε Active. Ο προγραμματιστής χρειάζεται μόνο να εγγραφεί στο onChange για την εκτέλεση παρενεργειών.

swift
import SwiftUI

@main
struct ActiveDemoApp: App {
    @Environment(\.scenePhase) private var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { oldPhase, newPhase in
            switch newPhase {
            case .active:
                print("Η σκηνή έγινε ενεργή")
                resumeWork()
            case .inactive:
                print("Η σκηνή έγινε ανενεργή")
                pauseWork()
            case .background:
                print("Η σκηνή πήγε στο παρασκήνιο")
                saveState()
            @unknown default:
                break
            }
        }
    }

    private func resumeWork() {
        // Συνέχιση αιτημάτων δικτύου, κινούμενων σχεδίων
    }

    private func pauseWork() {
        // Αναστολή εργασιών ευαίσθητων στον χρόνο
    }

    private func saveState() {
        // Αποθήκευση κατάστασης εφαρμογής
    }
}

Στο SwiftUI, το scenePhase είναι η μοναδική πηγή αλήθειας σχετικά με την κατάσταση της εφαρμογής. Το onChange επιτρέπει την εκτέλεση ενεργειών σε κάθε μετάβαση. Είναι σημαντικό να θυμάστε ότι το scenePhase είναι διαθέσιμο μόνο σε iOS 14+ και στο SwiftUI Lifecycle. Για εφαρμογές UIKit με οθόνες SwiftUI, χρησιμοποιήστε την προσέγγιση με UIApplicationDelegate.

Μεταβάσεις στην κατάσταση Active

Active μπορεί να επιτευχθεί με διάφορους τρόπους. Ο πρώτος και προφανής — ψυχρή εκκίνηση: ο χρήστης πατάει το εικονίδιο, η εφαρμογή πηγαίνει από Not Running μέσω Inactive σε Active. Ο δεύτερος — επιστροφή από το παρασκήνιο: ο χρήστης επιστρέφει στην εφαρμογή μέσω App Switcher, η εφαρμογή περνάει από Inactive και γίνεται Active. Ο τρίτος — επιστροφή από προσωρινή διακοπή: ο χρήστης τελειώνει μια κλήση, κλείνει το Control Center ή απαντά σε μια ειδοποίηση — η εφαρμογή επιστρέφει από Inactive σε Active.

Αλυσίδα μεταβάσεων σε Active

Not Running → Inactive → Active — ψυχρή εκκίνηση. Background → Inactive → Active — επιστροφή από παρασκήνιο. Inactive → Active — επιστροφή από προσωρινή διακοπή. Σε κάθε περίπτωση, το applicationDidBecomeActive καλείται, αλλά το πλαίσιο μπορεί να διαφέρει. Κατά την ψυχρή εκκίνηση, πριν από το Active, καλείται το didFinishLaunchingWithOptions, κατά την επιστροφή από παρασκήνιο — το willEnterForeground. Ο προγραμματιστής μπορεί να χρησιμοποιήσει αυτές τις διαφορές για να επιλέξει τη στρατηγική επαναφοράς κατάστασης.

ΣενάριοΔιαδρομή μετάβασηςCallbacks iOSCallbacks Android
Ψυχρή εκκίνησηNot Running → ActivedidFinishLaunching → didBecomeActiveonCreate → onStart → onResume
Επιστροφή από παρασκήνιοBackground → ActivewillEnterForeground → didBecomeActiveonRestart → onStart → onResume
Επιστροφή από SuspendedSuspended → ActivewillEnterForeground → didBecomeActiveonRestart → onStart → onResume
Μετά από διακοπήInactive → ActivedidBecomeActiveonResume

Σημαντική σημείωση: κατά την επιστροφή από Suspended, το iOS δεν καλεί το didFinishLaunchingWithOptions, επειδή η εφαρμογή είχε ήδη φορτωθεί στη μνήμη. Αυτό σημαίνει ότι ο κώδικας αρχικοποίησης που τοποθετείται σε αυτή τη μέθοδο δεν εκτελείται ξανά. Οι προγραμματιστές συχνά το ξεχνούν αυτό και μεταφέρουν την κρίσιμη λογική στο applicationWillEnterForeground ή applicationDidBecomeActive και για τα δύο σενάρια.

Active στο Android: κύκλος ζωής Activity

Στο Android, το αντίστοιχο του Active είναι η κατάσταση του Activity μετά την κλήση onResume(). Το Activity θεωρείται ενεργό όταν βρίσκεται στο προσκήνιο και δέχεται είσοδο χρήστη. Αυτή η κατάσταση αντιστοιχεί στην κορυφή της στοίβας Activity. Εάν εμφανιστεί ένα άλλο Activity από πάνω (ακόμα και μερικώς), το τρέχον Activity μεταβαίνει στην κατάσταση onPause — το αντίστοιχο του iOS Inactive.

Η βασική διαφορά του Android — πολλά Activity μπορούν να είναι ενεργά ταυτόχρονα σε λειτουργία multi-window (split screen, freeform). Σε αυτή την περίπτωση, το Activity με το οποίο αλληλεπιδρά ο χρήστης θεωρείται ενεργό, και το γειτονικό — ανασταλμένο (onPause). Το iOS δεν υποστηρίζει multi-window σε iPhone, μόνο σε iPad μέσω UIScene.

kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        // Η εφαρμογή έγινε ενεργή — συνεχίζουμε τις εργασίες
        resumeCameraPreview()
        startLocationUpdates()
        activateSensors()
    }

    override fun onPause() {
        super.onPause()
        // Η εφαρμογή χάνει δραστηριότητα — απελευθερώνουμε πόρους
        releaseCamera()
        stopLocationUpdates()
        deactivateSensors()
    }

    private fun resumeCameraPreview() {
        // Εκκίνηση προεπισκόπησης κάμερας (απαιτεί άδεια)
        cameraProvider?.unbindAll()
        cameraProvider?.bindToLifecycle(
            this,
            cameraSelector,
            preview,
            imageAnalyzer
        )
    }

    private fun startLocationUpdates() {
        val locationRequest = LocationRequest.Builder(
            Priority.PRIORITY_HIGH_ACCURACY, 5000
        ).build()
        locationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.getMainLooper()
        )
    }
}

Ο κώδικας δείχνει τον χειρισμό του Active στο Android μέσω onResume/onPause. Το onResume συνεχίζει την εργασία με την κάμερα, τη γεωτοποθεσία και τους αισθητήρες — πόρους που πρέπει να είναι ενεργοί μόνο όταν η εφαρμογή είναι ορατή στον χρήστη. Το onPause απελευθερώνει αυτούς τους πόρους για να μην εξαντλείται η μπαταρία. Το CameraX lifecycle-aware API σταματά αυτόματα την προεπισκόπηση στο onPause.

Βέλτιστες πρακτικές χειρισμού Active

Πρώτος κανόνας — μην εκτελείτε βαριές λειτουργίες στο applicationDidBecomeActive ή onResume. Φόρτωση δεδομένων, ανάλυση JSON, εργασία με βάση δεδομένων — όλα αυτά πρέπει να είναι ασύγχρονα και να μην μπλοκάρουν το κύριο νήμα. Χρησιμοποιήστε GCD (DispatchQueue) στο iOS και Coroutines στο Kotlin για εργασίες παρασκηνίου. Το κύριο νήμα πρέπει μόνο να ενημερώνει το UI και να ξεκινά ασύγχρονες λειτουργίες.

Δεύτερος κανόνας — συγχρονίστε την κατάσταση σε κάθε επιστροφή σε Active. Ο χρήστης μπορεί να έχει αλλάξει ρυθμίσεις στην εφαρμογή συστήματος, να έχει λάβει push ειδοποίηση ή να έχει ενημερώσει δεδομένα σε άλλη εφαρμογή. Ελέγξτε την επικαιρότητα της κρυφής μνήμης κατά τη μετάβαση σε Active — ίσως τα δεδομένα έχουν παλιώσει κατά την απουσία του χρήστη.

Τρίτος κανόνας — μην βασίζεστε στο Active ως τη μοναδική κατάσταση. Η εφαρμογή μπορεί να παραλείψει το Active και να πάει απευθείας από Not Running σε Background (εάν εκτελείται σε παρασκήνιο). Στο iOS, αυτό συμβαίνει κατά την εκκίνηση μέσω push ειδοποίησης με την επιλογή content-available. Στο Android — κατά την εκκίνηση μέσω BroadcastReceiver. Να ελέγχετε πάντα την τρέχουσα κατάσταση πριν από την εκτέλεση λειτουργιών UI.

Τέταρτος κανόνας — χρησιμοποιήστε το Activity Result API στο Android αντί για onActivityResult. Αυτό επιτρέπει τον χειρισμό του αποτελέσματος κλήσης κάμερας, γκαλερί ή αδειών απευθείας στην κατάσταση Active χωρίς απώλεια δεδομένων κατά την αναδημιουργία του Activity. Για iOS, χρησιμοποιήστε async/await με UIApplication.shared.open για διαλόγους συστήματος.

swift
import UIKit

final class ActiveStateManager {
    static let shared = ActiveStateManager()
    private var isActive = false

    func setActive(_ active: Bool) {
        isActive = active
        if active {
            NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
        }
    }

    func performWhenActive(_ block: @escaping () -> Void) {
        if isActive {
            block()
        } else {
            // Αναβολή εκτέλεσης μέχρι την επιστροφή σε Active
            NotificationCenter.default.addObserver(
                forName: .appDidBecomeActive,
                object: nil,
                queue: .main
            ) { _ in
                block()
            }
        }
    }
}

extension Notification.Name {
    static let appDidBecomeActive = Notification.Name("appDidBecomeActive")
}

Ο κώδικας δείχνει έναν διαχειριστή κατάστασης Active που επιτρέπει σε άλλα στοιχεία της εφαρμογής να ελέγχουν την τρέχουσα ενεργή κατάσταση. Το performWhenActive είτε εκτελεί το μπλοκ αμέσως (εάν η εφαρμογή είναι ενεργή) είτε αναβάλλει την εκτέλεση μέχρι την επιστροφή σε Active. Αυτό είναι χρήσιμο για υπηρεσίες που πρέπει να εκτελέσουν μια ενέργεια αφού ο χρήστης επιστρέψει στην εφαρμογή.

Συχνές Ερωτήσεις

Πόσο συχνά καλείται το applicationDidBecomeActive;

Η μέθοδος καλείται κάθε φορά που η εφαρμογή μεταβαίνει σε ενεργή κατάσταση: κατά την πρώτη εκκίνηση, κατά την επιστροφή από το παρασκήνιο, μετά το κλείσιμο του Control Center ή Notification Center, μετά το τέλος μιας κλήσης. Σε μια κανονική συνεδρία μπορεί να κληθεί 5–10 φορές ανάλογα με τις ενέργειες του χρήστη. Μην τοποθετείτε εφάπαξ αρχικοποίηση σε αυτή τη μέθοδο.

Ποια είναι η διαφορά μεταξύ Active και Visible στο iOS;

Visible — ένας ανεπίσημος όρος που σημαίνει ότι η εφαρμογή είναι ορατή στην οθόνη, αλλά μπορεί να μην λαμβάνει γεγονότα (για παράδειγμα, μερικώς καλυμμένη από άλλο παράθυρο σε iPad). Active — η επίσημη κατάσταση στην οποία η εφαρμογή είναι και ορατή και διαδραστική. Σε iPhone, μια Visible εφαρμογή είναι πάντα Active, σε iPad είναι πιθανή η κατάσταση Visible + Inactive.

Τι είναι το didBecomeActive vs willEnterForeground;

willEnterForeground καλείται κατά την επιστροφή από το παρασκήνιο, αλλά η εφαρμογή δεν είναι ακόμη ενεργή — βρίσκεται σε Inactive. didBecomeActive καλείται αφού η εφαρμογή γίνει πλήρως διαδραστική. Εάν πρέπει να εκτελέσετε μια ενέργεια πριν ο χρήστης δει τη διεπαφή — χρησιμοποιήστε το willEnterForeground. Εάν μετά την εμφάνιση — το didBecomeActive.

Μπορεί μια εφαρμογή να είναι Active χωρίς ορατό UI;

Όχι. Το Active προϋποθέτει ότι η εφαρμογή βρίσκεται στο προσκήνιο και εμφανίζεται στην οθόνη. Χωρίς ορατό UI, η εφαρμογή μπορεί να είναι σε Background ή Suspended. Εξαίρεση — iPad multi-window, όπου ένα παράθυρο μπορεί να είναι ενεργό και το άλλο όχι, αλλά και τα δύο είναι ορατά. Το VoiceOver και το μαγνητόφωνο δεν αλλάζουν αυτόν τον κανόνα.

Πώς να δοκιμάσετε τη μετάβαση σε Active στον προσομοιωτή;

Στον προσομοιωτή iOS, πατήστε Cmd+Shift+H για να πάτε στην Αρχική οθόνη (η εφαρμογή πηγαίνει σε Background), στη συνέχεια κάντε ξανά κλικ στο εικονίδιο της εφαρμογής. Χρησιμοποιήστε Cmd+L για κλείδωμα οθόνης (willResignActive) και ξεκλείδωμα (didBecomeActive). Για δοκιμή Inactive, καλέστε το Control Center (Cmd+Shift+; για πληκτρολόγιο macOS) ή το Notification Center.

Περίληψη

  • Active — κατάσταση εφαρμογής στο προσκήνιο με πλήρη πρόσβαση στην είσοδο χρήστη και μέγιστη προτεραιότητα πόρων
  • iOS UIKit — applicationDidBecomeActive για συνέχιση κινούμενων σχεδίων, χρονοδιακοπτών και αισθητήρων
  • SwiftUI — scenePhase .active μέσω Environment, onChange για παρενέργειες
  • Android — onResume/onPause ως αντίστοιχο Active/Inactive, με υποστήριξη multi-window
  • Μεταβάσεις — Active επιτυγχάνεται από Not Running (ψυχρή εκκίνηση), Background και Inactive
  • Πόροι — βαριές λειτουργίες στο didBecomeActive πρέπει να είναι ασύγχρονες, να μην μπλοκάρουν το κύριο νήμα
  • Συγχρονισμός — έλεγχος επικαιρότητας κρυφής μνήμης και δεδομένων σε κάθε επιστροφή σε Active

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης