Inactive — övergångstillstånd i applikationens livscykel mellan Active och Background, där applikationen är synlig på skärmen men inte tar emot beröringshändelser. Vi förklarar hur Inactive uppstår på iOS och Android, vilka delegatmetoder som ansvarar för det och hur man korrekt hanterar avbrott — samtal, aviseringar och systemgester.
Huvudpunkter
Inactive — ett mellanliggande tillstånd i den mobila applikationens livscykel som uppstår vid övergången mellan Active och Background. I detta tillstånd är applikationen fortfarande i förgrunden och synlig för användaren, men tar inte emot beröringshändelser, tangenttryckningar eller andra UI-händelser. Systemet blockerar överföringen av händelser till applikationen, men UI förblir på skärmen och minimeras inte.
Inactive’s natur är tillfällig. Detta tillstånd varar exakt så länge som systemavbrottet varar: från 0.1 sekund vid snabb stängning av Control Center till några sekunder vid ett inkommande samtal med samtalskärm. Efter avbrottets slut återgår applikationen antingen till Active eller går till Background om användaren har växlat till en annan app. Inactive är det enda tillstånd från vilket övergång är möjlig i båda riktningarna: tillbaka till Active eller vidare till Background.
På iOS hanteras Inactive automatiskt av systemet. Utvecklaren kan inte förlänga eller förkorta tiden i Inactive — det kontrolleras helt av UIApplication. Det enda utvecklaren kan göra är att korrekt hantera övergången till Inactive via applicationWillResignActive och återkomsten via applicationDidBecomeActive. På Android är motsvarigheten onPause, även om semantiken skiljer sig: onPause anropas även vid partiell täckning av Activity av en annan komponent.
På iOS är Inactive ett separat tillstånd i applikationens livscykel (ett av fem: Not Running, Active, Inactive, Background, Suspended). På Android finns ingen direkt motsvarighet — onPause signalerar att Activity förlorar inmatningsfokus men kan förbli synligt (till exempel vid öppning av en dialog). Den viktigaste skillnaden: iOS Inactive är applikationens tillstånd som helhet, Android onPause är tillståndet för ett specifikt Activity. I multi-window-läge på Android kan ett Activity vara i onPause (utan fokus) medan ett annat är i onResume (med fokus).
| Egenskap | iOS Inactive | Android onPause |
|---|---|---|
| UI synligt | Ja | Ja (delvis eller helt) |
| Beröringshändelser | Tar inte emot | Tar inte emot |
| Varaktighet | Tills avbrottet slutar | Tills fokus återvänder eller övergång till bakgrunden |
| Nästa tillstånd | Active eller Background | onResume eller onStop |
| Nivå | Applikation (UIApplication) | Activity |
| Multi-window | En scen aktiv | Flera Activity i onPause |
Inactive på iOS uppstår i flera strikt definierade scenarier. Användaren anropar Control Center (svep nedåt från högra övre hörnet på iPhone X+ eller svep uppåt på äldre modeller). Användaren öppnar Notification Center (svep nedåt från vänstra övre hörnet). Ett inkommande samtal kommer — systemet visar samtalskärmen ovanför applikationen. Systemtillstånd begärs — geolokalisering, mikrofon, kamera, kontakter. På iPad startas Slide Over eller Split View — den aktiva scenen blir Inactive.
På Android uppstår onPause (motsvarigheten till Inactive) i ett ännu bredare spektrum av situationer. Öppning av dialogruta (AlertDialog, DialogFragment). Partiell täckning av Activity av ett annat Activity (till exempel transparent Activity för autentisering). Skärmrotation (Activity återskapas, sekvens: onPause → onStop → onDestroy → onCreate → onStart → onResume). Multi-window-läge — det inaktiva fönstret får onPause. Var och en av dessa händelser kräver avstängning av resurskrävande operationer för att spara batteri och prestanda.
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) {
// Applikationen går in i Inactive — systemavbrott
print("Avbrott: Control Center, samtal eller systemvarning")
// Stoppning av tidskänsliga operationer
pauseVideoPlayback()
stopContinuousDataCollection()
hideSensitiveInformation()
// Avisering av komponenter
NotificationCenter.default.post(name: .systemInterruptionBegan, object: nil)
}
// Återkomst från Inactive till Active
func applicationDidBecomeActive(_ application: UIApplication) {
resumeVideoPlayback()
restartDataCollection()
NotificationCenter.default.post(name: .systemInterruptionEnded, object: nil)
}
private func pauseVideoPlayback() {
// Stoppning av video för att undvika ljudöverlappning
}
private func hideSensitiveInformation() {
// Döljande av känslig data vid skärmbild
// Control Center/App Switcher tar skärmbild av UI
}
}Koden visar hantering av Inactive i UIKit. applicationWillResignActive stoppar videon, stoppar datainsamling och döljer känslig information. Detta är viktigt eftersom systemet tar en skärmbild av det aktuella UI:t när Control Center eller App Switcher öppnas — användaren kan se konfidentiell data i förhandsvisningen. NotificationCenter tillåter applikationskomponenter att prenumerera på avbrottshändelser.
På iOS hanteras Inactive av ett par metoder: applicationWillResignActive (övergång till Inactive) och applicationDidBecomeActive (återkomst från Inactive). Dessa metoder är en del av UIApplicationDelegate och anropas för varje övergång genom Inactive. Sedan iOS 13 och UISceneDelegate har sceneWillResignActive och sceneDidBecomeActive lagts till för multi-window-scenarier.
På iPad med iOS 13+ kan en applikation ha flera scener (fönster). Varje scen har sin egen livscykel. En scen kan bli Inactive (användaren har växlat till en annan scen), medan en annan förblir Active. Detta är en viktig skillnad jämfört med iPhone, där Inactive är ett globalt tillstånd för hela applikationen. Vid utveckling för iPad måste Inactive hanteras separat för varje scen.
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
// Scenen blir inaktiv
func sceneWillResignActive(_ scene: UIScene) {
// På iPad förlorar denna scen fokus, men andra kan vara aktiva
print("Scenen förlorar aktivitet")
// Stoppning av denna scenes uppgifter
pauseSceneSpecificOperations()
}
// Scenen blir aktiv
func sceneDidBecomeActive(_ scene: UIScene) {
print("Scenen har blivit aktiv")
resumeSceneSpecificOperations()
}
private func pauseSceneSpecificOperations() {
// Stoppning av operationer specifika för denna scen
}
private func resumeSceneSpecificOperations() {
// Återupptagning av operationer vid fokusåterkomst
}
}
// AppDelegate förblir ingångspunkt, delegerar till scener
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
return UISceneConfiguration(
name: "Default Configuration",
sessionRole: connectingSceneSession.role
)
}
}Koden visar SceneDelegate för hantering av Inactive på scenivå. sceneWillResignActive anropas när ett specifikt fönster förlorar fokus — detta kan inträffa vid växling mellan fönster på iPad. AppDelegate konfigurerar UISceneConfiguration för multi-window-stöd. Varje scen har ett oberoende tillstånd och utvecklaren måste hantera dem separat.
På Android är den direkta motsvarigheten till iOS Inactive metoden onPause() i Activitys livscykel. Den anropas när Activity förlorar inmatningsfokus men kan förbli synligt. Typiska scenarier: öppning av dialogruta, start av ett annat Activity i samma applikation, inkommande samtal, tryckning på Home- eller Recents-knappen. I onPause bör utvecklaren stoppa resurskrävande operationer — animationer, videouppspelning, arbete med kameran.
En viktig skillnad på Android — onPause kommer alltid före onStop, men inte tvärtom. Ett Activity kan få onPause utan onStop (till exempel vid öppning av ett transparent Activity). Dessutom kan onPause anropas flera gånger under Activitys livstid — vid varje fokusändring. Placera inte engångslogik i onPause — använd onStop för slutliga operationer och onPause endast för att stoppa interaktiva åtgärder.
class VideoPlayerActivity : AppCompatActivity() {
private var exoPlayer: ExoPlayer? = null
private var currentPosition: Long = 0L
override fun onPause() {
super.onPause()
// Applikationen förlorar fokus — pausa video
exoPlayer?.let { player ->
if (player.isPlaying) {
currentPosition = player.currentPosition
player.pause()
}
}
// Dölj känslig data (GDPR/bankskärmar)
if (window.decorView.systemUiVisibility and
View.SYSTEM_UI_FLAG_SECURE == 0
) {
hideSensitiveOverlay()
}
}
override fun onResume() {
super.onResume()
// Fokus återvänder — återuppta uppspelning
exoPlayer?.seekTo(currentPosition)
exoPlayer?.play()
showSensitiveOverlay()
}
private fun hideSensitiveOverlay() {
// Lägg svart skärm över finansiell data
}
}Koden visar korrekt hantering av onPause för en videospelare. ExoPlayer pausas vid förlust av fokus och uppspelningspositionen sparas. Vid återkomst till onResume återupptar spelaren uppspelningen från den sparade positionen. Dessutom visas mönstret för att dölja känslig data — viktigt för finansiella och medicinska applikationer som kräver skydd mot skärmbilder vid växling.
Första regeln — dölj konfidentiell data vid övergång till Inactive. När användaren öppnar Control Center eller App Switcher tar iOS en skärmbild av den aktuella skärmen. På Android liknande — systemet visar en förhandsvisning av det senaste Activity i Recents. Använd UIApplication.shouldSnapshotSecureApp (iOS 16+) eller FLAG_SECURE (Android) för att skydda konfidentiella skärmar.
Andra regeln — stoppa animationer och media. Inactive är inte den bästa tiden för videouppspelning eller animationer, eftersom användaren inte ser dem. Dessutom kan uppspelning i bakgrunden leda till överlappning av ljud med systemljud (samtal, avisering). Stoppa AVPlayer, ExoPlayer och UIView.animate vid övergång till Inactive och återuppta vid återkomst till Active.
Tredje regeln — blockera datainmatning. Om applikationen innehåller inmatningsformulär eller utkast, blockera tangentbordet och inmatningsfälten vid övergång till Inactive. Detta förhindrar oavsiktlig inmatning vid återkomst och skyddar mot avlyssning av data via systemöverlagringar. På iOS, inaktivera first responder (view.endEditing(true)), på Android — rensa fokus (currentFocus?.clearFocus()).
Fjärde regeln — utför inte långa operationer i applicationWillResignActive eller onPause. Dessa metoder bör slutföras på bråkdelar av en sekund. Om du behöver spara en stor mängd data, påbörja sparningen i en bakgrundstråd och slutför den i applicationDidEnterBackground eller onStop. iOS ger 5 sekunder för att exekvera applicationWillResignActive, varefter systemet kan tvångsavsluta applikationen.
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
}
}
// Användning i AppDelegate
func applicationWillResignActive(_ application: UIApplication) {
SecureOverlayManager().showBlurOverlay()
}
func applicationDidBecomeActive(_ application: UIApplication) {
SecureOverlayManager().removeBlurOverlay()
}Koden visar implementeringen av en säker överlagring för dataskydd vid övergång till Inactive. En UIVisualEffectView med oskärpa (blur) placeras ovanför hela UI:t vid övergång till Inactive och tas bort vid återkomst till Active. Detta garanterar att konfidentiell data inte syns på skärmbilder av App Switcher och Control Center. På liknande sätt kan UIImageView med logotyp användas för en varumärkesöverlagring.
Vanliga frågor
Ja. Inactive är ett obligatoriskt mellanliggande tillstånd innan övergång till Background på iOS. Applikationen kan inte gå direkt från Active till Background — först blir den Inactive, sedan Background. På Android liknande: onPause anropas alltid före onStop. Detta ger utvecklaren möjlighet att förbereda data för sparande innan den helt går till bakgrunden.
Ja. På iPad vid start av Slide Over eller Split View blir den aktiva scenen Inactive, även om inget systemavbrott inträffar — användaren interagerar helt enkelt med en annan scen. Detta är en multi-window-funktion i iPadOS. På iPhone orsakas Inactive alltid av ett systemavbrott — samtal, avisering, Control Center eller Notification Center.
Vanligtvis mellan 0.1 och 2 sekunder. Vid ett inkommande samtal med samtalskärm — upp till 30 sekunder (tills användaren svarar eller avvisar samtalet). iOS begränsar inte tiden i Inactive tvångsmässigt, men systemet kan avsluta applikationen om den inte svarar på händelser (watchdog). På Android har onPause ingen tidsbegränsning, men det rekommenderas att slutföra arbetet inom 200 ms.
ScenePhase.inactive — värdet på enum ScenePhase, som ställs in när scenen är i förgrunden men inte tar emot händelser. I SwiftUI kan du observera det via @Environment(\.scenePhase) och reagera via onChange. Vid övergång från .active till .inactive, stoppa timer och animationer. Vid återkomst till .active — återuppta. Vid övergång till .background — spara tillståndet.
Nej, endast för applikationer som arbetar med konfidentiell data: bank, medicin, företag, meddelandetjänster med privata chattar. För spel och underhållningsapplikationer krävs inte döljande av UI. Att stoppa spelet och ljudet vid Inactive är dock god praxis för att undvika överlappning av ljud med systemaviseringar. Apple rekommenderar att dölja känslig data, men kräver det inte.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också