Inactive — esența, starea de tranziție între Active și Background

Autor: IT Sectr Publicat: 2026-03-03 Timp de citire: 10 min

Inactive — stare de tranziție a ciclului de viață al aplicației între Active și Background, în care aplicația este vizibilă pe ecran, dar nu primește evenimente de atingere. Explicăm cum apare Inactive pe iOS și Android, ce metode delegate răspund pentru el și cum să gestionăm corect întreruperile — apeluri, notificări și gesturi sistemice.

Principalele puncte

  • Inactive — aplicația este vizibilă pe ecran, dar nu primește evenimente tactile din cauza unei întreruperi sistemice
  • applicationWillResignActive — metoda principală care semnalizează trecerea în Inactive pe iOS
  • Caracter temporar — Inactive durează de la fracțiuni de secundă până la câteva secunde, apoi urmează tranziția în Active sau Background
  • Cauze — apel primit, Control Center, Notification Center, alertă sistemică, Apple Pay, Siri
  • SwiftUI — scenePhase .inactive este echivalentul Inactive în UIKit

Inactive — esența stării de tranziție

Inactive — stare intermediară a ciclului de viață al aplicației mobile care apare la tranziția între Active și Background. În această stare, aplicația se află încă în prim-plan și este vizibilă utilizatorului, dar nu primește evenimente tactile, apăsări de taste sau alte evenimente UI. Sistemul blochează transmiterea evenimentelor către aplicație, dar UI rămâne pe ecran și nu se minimizează.

Natura Inactive este temporară. Această stare durează exact cât durează întreruperea sistemică: de la 0.1 secunde la închiderea rapidă a Control Center până la câteva secunde la un apel primit cu ecran de apel. După terminarea întreruperii, aplicația fie revine în Active, fie trece în Background, dacă utilizatorul a comutat la o altă aplicație. Inactive este singura stare din care este posibilă tranziția în ambele direcții: înapoi în Active sau mai departe în Background.

Pe iOS, Inactive este gestionat automat de sistem. Dezvoltatorul nu poate prelungi sau scurta timpul petrecut în Inactive — este complet controlat de UIApplication. Singurul lucru pe care dezvoltatorul îl poate face este să gestioneze corect intrarea în Inactive prin applicationWillResignActive și revenirea prin applicationDidBecomeActive. Pe Android, analogul este onPause, deși semantica diferă: onPause este apelat chiar și la acoperirea parțială a Activity de către o altă componentă.

Compararea Inactive pe iOS și Android

Pe iOS, Inactive este o stare separată a ciclului de viață al aplicației (una dintre cele cinci: Not Running, Active, Inactive, Background, Suspended). Pe Android nu există un analog direct — onPause semnalizează că Activity pierde focusul de intrare, dar poate rămâne vizibil (de exemplu, la deschiderea unui dialog). Diferența cheie: Inactive pe iOS este starea aplicației în ansamblu, onPause pe Android este starea unui Activity specific. În modul multi-window pe Android, un Activity poate fi în onPause (fără focus), iar altul în onResume (cu focus).

CaracteristicăiOS InactiveAndroid onPause
UI vizibilDaDa (parțial sau complet)
Evenimente tactileNu primeșteNu primește
DuratăPână la terminarea întreruperiiPână la revenirea focusului sau trecerea în fundal
Următoarea stareActive sau BackgroundonResume sau onStop
NivelAplicație (UIApplication)Activity
Multi-windowO scenă activăMai multe Activity în onPause

Când apare Inactive

Inactive pe iOS apare în câteva scenarii strict definite. Utilizatorul invocă Control Center (deplasare în jos din colțul dreapta sus pe iPhone X+ sau deplasare în sus pe modelele vechi). Utilizatorul deschide Notification Center (deplasare în jos din colțul stânga sus). Sosește un apel primit — sistemul afișează ecranul de apel deasupra aplicației. Se solicită o permisiune sistemică — geolocalizare, microfon, cameră, contacte. Pe iPad, se lansează Slide Over sau Split View — scena activă devine Inactive.

Pe Android, onPause (analogul Inactive) apare într-o gamă și mai largă de situații. Deschiderea unei ferestre de dialog (AlertDialog, DialogFragment). Acoperirea parțială a Activity de către un alt Activity (de exemplu, un Activity transparent pentru autentificare). Rotirea ecranului (Activity este recreat, secvența: onPause → onStop → onDestroy → onCreate → onStart → onResume). Modul multi-window — fereastra inactivă primește onPause. Fiecare dintre aceste evenimente necesită suspendarea operațiilor consumatoare de resurse pentru economisirea bateriei și a performanței.

swift
import UIKit

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

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func applicationWillResignActive(_ application: UIApplication) {
        // Aplicația trece în Inactive — întrerupere sistemică
        print("Întrerupere: Control Center, apel sau alertă sistemică")

        // Suspendarea operațiilor sensibile la timp
        pauseVideoPlayback()
        stopContinuousDataCollection()
        hideSensitiveInformation()

        // Notificarea componentelor
        NotificationCenter.default.post(name: .systemInterruptionBegan, object: nil)
    }

    // Revenirea din Inactive în Active
    func applicationDidBecomeActive(_ application: UIApplication) {
        resumeVideoPlayback()
        restartDataCollection()
        NotificationCenter.default.post(name: .systemInterruptionEnded, object: nil)
    }

    private func pauseVideoPlayback() {
        // Oprirea videoclipului pentru a nu se suprapune sunetul
    }

    private func hideSensitiveInformation() {
        // Ascunderea datelor sensibile la captura de ecran
        // Control Center/App Switcher fac captură de ecran UI
    }
}

Codul arată gestionarea Inactive în UIKit. applicationWillResignActive oprește videoclipul, întrerupe colectarea datelor și ascunde informațiile sensibile. Acest lucru este important deoarece la deschiderea Control Center sau App Switcher, sistemul face o captură de ecran a UI-ului curent — utilizatorul poate vedea date confidențiale în previzualizare. NotificationCenter permite componentelor aplicației să se aboneze la evenimente de întrerupere.

Inactive pe iOS: Swift și UIKit

Pe iOS, Inactive este gestionat de o pereche de metode: applicationWillResignActive (intrarea în Inactive) și applicationDidBecomeActive (revenirea din Inactive). Aceste metode fac parte din UIApplicationDelegate și sunt apelate pentru fiecare tranziție prin Inactive. De la iOS 13 și UISceneDelegate, li s-au adăugat sceneWillResignActive și sceneDidBecomeActive pentru scenarii multi-window.

SceneDelegate și Inactive multi-window

Pe iPad cu iOS 13+, aplicația poate avea mai multe scene (ferestre). Fiecare scenă are propriul ciclu de viață. O scenă poate deveni Inactive (utilizatorul a comutat la o altă scenă), în timp ce alta rămâne Active. Aceasta este o diferență importantă față de iPhone, unde Inactive este o stare globală pentru întreaga aplicație. La dezvoltarea pentru iPad, Inactive trebuie gestionat separat pentru fiecare scenă.

swift
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    // Scena devine inactivă
    func sceneWillResignActive(_ scene: UIScene) {
        // Pe iPad, această scenă pierde focusul, dar altele pot fi active
        print("Scena pierde activitatea")

        // Suspendarea sarcinilor acestei scene
        pauseSceneSpecificOperations()
    }

    // Scena devine activă
    func sceneDidBecomeActive(_ scene: UIScene) {
        print("Scena a devenit activă")
        resumeSceneSpecificOperations()
    }

    private func pauseSceneSpecificOperations() {
        // Suspendarea operațiilor specifice acestei scene
    }

    private func resumeSceneSpecificOperations() {
        // Reluarea operațiilor la revenirea focusului
    }
}

// AppDelegate rămâne punct de intrare, delegă scenelor
@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        configurationForConnecting connectingSceneSession: UISceneSession,
        options: UIScene.ConnectionOptions
    ) -> UISceneConfiguration {
        return UISceneConfiguration(
            name: "Default Configuration",
            sessionRole: connectingSceneSession.role
        )
    }
}

Codul arată SceneDelegate pentru gestionarea Inactive la nivel de scenă. sceneWillResignActive este apelat când o anumită fereastră pierde focusul — acest lucru poate apărea la comutarea între ferestre pe iPad. AppDelegate configurează UISceneConfiguration pentru suport multi-window. Fiecare scenă are o stare independentă, iar dezvoltatorul trebuie să le gestioneze separat.

Inactive pe Android: onPause și vizibilitate

Pe Android, analogul direct al Inactive iOS este metoda onPause() a ciclului de viață al Activity. Este apelată când Activity pierde focusul de intrare, dar poate rămâne vizibil. Scenarii tipice: deschiderea unei ferestre de dialog, lansarea unui alt Activity în aceeași aplicație, un apel primit, apăsarea butonului Home sau Recents. În onPause, dezvoltatorul trebuie să suspende operațiile consumatoare de resurse — animații, redare video, lucrul cu camera.

O diferență importantă pe Android — onPause precedă întotdeauna onStop, dar inversul nu este valabil. Activity poate primi onPause fără onStop (de exemplu, la deschiderea unui Activity transparent). De asemenea, onPause poate fi apelat de mai multe ori pe durata vieții Activity — la fiecare schimbare de focus. Nu plasați logică unică în onPause — folosiți onStop pentru operații finale și onPause doar pentru suspendarea acțiunilor interactive.

kotlin
class VideoPlayerActivity : AppCompatActivity() {

    private var exoPlayer: ExoPlayer? = null
    private var currentPosition: Long = 0L

    override fun onPause() {
        super.onPause()
        // Aplicația pierde focusul — oprim videoclipul
        exoPlayer?.let { player ->
            if (player.isPlaying) {
                currentPosition = player.currentPosition
                player.pause()
            }
        }
        // Ascundem datele sensibile (GDPR/ecrane bancare)
        if (window.decorView.systemUiVisibility and
            View.SYSTEM_UI_FLAG_SECURE == 0
        ) {
            hideSensitiveOverlay()
        }
    }

    override fun onResume() {
        super.onResume()
        // Revenirea focusului — reluăm redarea
        exoPlayer?.seekTo(currentPosition)
        exoPlayer?.play()
        showSensitiveOverlay()
    }

    private fun hideSensitiveOverlay() {
        // Suprapunem un ecran negru peste datele financiare
    }
}

Codul arată gestionarea corectă a onPause pentru un player video. ExoPlayer este suspendat la pierderea focusului, iar poziția de redare este salvată. La revenirea în onResume, playerul reia redarea de la poziția salvată. În plus, este arătat modelul de ascundere a datelor sensibile — important pentru aplicațiile financiare și medicale care necesită protecție împotriva capturilor de ecran la comutare.

Cele mai bune practici de gestionare Inactive

Prima regulă — ascundeți datele confidențiale la trecerea în Inactive. Când utilizatorul deschide Control Center sau App Switcher, iOS face o captură de ecran a ecranului curent. Pe Android, similar — sistemul arată previzualizarea ultimului Activity în Recents. Folosiți UIApplication.shouldSnapshotSecureApp (iOS 16+) sau FLAG_SECURE (Android) pentru protejarea ecranelor confidențiale.

A doua regulă — suspendați animațiile și media. Inactive nu este cel mai bun moment pentru redarea video sau animații, deoarece utilizatorul nu le vede. Mai mult, redarea în fundal poate duce la suprapunerea sunetelor peste sunetele sistemice (apel, notificare). Opriți AVPlayer, ExoPlayer și UIView.animate la intrarea în Inactive și reluați la revenirea în Active.

A treia regulă — blocați introducerea datelor. Dacă aplicația conține formulare de introducere sau schițe, blocați tastatura și câmpurile de intrare la intrarea în Inactive. Acest lucru previne introducerea accidentală la revenire și protejează împotriva interceptării datelor prin suprapuneri sistemice. Pe iOS, dezactivați first responder (view.endEditing(true)), pe Android — ștergeți focusul (currentFocus?.clearFocus()).

A patra regulă — nu efectuați operații lungi în applicationWillResignActive sau onPause. Aceste metode trebuie să se finalizeze în fracțiuni de secundă. Dacă trebuie să salvați un volum mare de date, începeți salvarea într-un fir de execuție în fundal și finalizați-o în applicationDidEnterBackground sau onStop. iOS oferă 5 secunde pentru executarea applicationWillResignActive, după care sistemul poate încheia forțat aplicația.

swift
import UIKit

final class SecureOverlayManager {
    private var blurView: UIVisualEffectView?

    func showBlurOverlay() {
        guard let window = UIApplication.shared.keyWindow,
              blurView == nil
        else { return }

        let blur = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
        blur.frame = window.bounds
        blur.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        window.addSubview(blur)
        blurView = blur
    }

    func removeBlurOverlay() {
        blurView?.removeFromSuperview()
        blurView = nil
    }
}

// Utilizare în AppDelegate
func applicationWillResignActive(_ application: UIApplication) {
    SecureOverlayManager().showBlurOverlay()
}

func applicationDidBecomeActive(_ application: UIApplication) {
    SecureOverlayManager().removeBlurOverlay()
}

Codul arată implementarea unei suprapuneri sigure pentru protejarea datelor la trecerea în Inactive. UIVisualEffectView cu efect de blur este plasat deasupra întregului UI la intrarea în Inactive și eliminat la revenirea în Active. Acest lucru garantează că datele confidențiale nu vor fi vizibile în capturile de ecran App Switcher și Control Center. Similar, se poate folosi UIImageView cu un logo pentru o suprapunere branduită.

Întrebări frecvente

Inactive precedă întotdeauna Background?

Da. Inactive este o stare intermediară obligatorie înainte de trecerea în Background pe iOS. Aplicația nu poate trece direct din Active în Background — mai întâi devine Inactive, apoi Background. Pe Android, similar: onPause este întotdeauna apelat înainte de onStop. Acest lucru oferă dezvoltatorului posibilitatea de a pregăti datele pentru salvare înainte de a trece complet în fundal.

Poate aplicația să primească Inactive fără întrerupere?

Da. Pe iPad la lansarea Slide Over sau Split View, scena activă devine Inactive, deși nu are loc nicio întrerupere sistemică — utilizatorul interacționează pur și simplu cu o altă scenă. Aceasta este o caracteristică multi-window a iPadOS. Pe iPhone, Inactive este întotdeauna cauzat de o întrerupere sistemică — apel, notificare, Control Center sau Notification Center.

Cât timp poate rămâne aplicația în Inactive?

De obicei între 0.1 și 2 secunde. La un apel primit cu ecran de apel — până la 30 de secunde (până când utilizatorul răspunde sau respinge apelul). iOS nu limitează forțat timpul în Inactive, dar sistemul poate încheia aplicația dacă nu răspunde la evenimente (watchdog). Pe Android, onPause nu are limită de timp, dar se recomandă finalizarea lucrului în 200 ms.

Ce este scenePhase în SwiftUI la Inactive?

ScenePhase.inactive — valoarea enum ScenePhase, setată când scena se află în prim-plan dar nu primește evenimente. În SwiftUI, o puteți observa prin @Environment(\.scenePhase) și reacționa prin onChange. La trecerea din .active în .inactive, suspendați timer-ele și animațiile. La revenirea în .active — reluați. La trecerea în .background — salvați starea.

Trebuie ascuns UI la Inactive pentru toate aplicațiile?

Nu, doar pentru aplicațiile care lucrează cu date confidențiale: bancare, medicale, corporative, mesagerii cu chat-uri private. Pentru jocuri și aplicații de divertisment, ascunderea UI nu este necesară. Cu toate acestea, suspendarea jocului și a sunetului la Inactive este o bună practică pentru a evita suprapunerea sunetelor peste notificările sistemice. Apple recomandă ascunderea datelor sensibile, dar nu o impune.

Rezumat

  • Inactive — stare de tranziție între Active și Background, aplicația vizibilă dar neinteractivă
  • Cauze — Control Center, Notification Center, apel primit, permisiuni sistemice, Siri, Apple Pay
  • Gestionare iOS — applicationWillResignActive pentru suspendarea animațiilor, mediei și ascunderea datelor sensibile
  • SwiftUI — scenePhase .inactive prin Environment, onChange pentru efecte secundare
  • Android — onPause ca analog, cu suport multi-window și acoperire parțială a Activity
  • Securitate — suprapunere blur sau FLAG_SECURE pentru protecție împotriva capturilor App Switcher și Control Center
  • Caracter temporar — Inactive durează până la terminarea întreruperii, apoi revenire în Active sau trecere în Background

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și