Background: noțiuni de bază, lucrul aplicației în fundal pe iOS și Android

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

Background — starea ciclului de viață al aplicației în care aceasta continuă să ruleze, dar nu este afișată pe ecran. Explicăm noțiunile de bază ale lucrului în fundal pe iOS și Android: restricții, timeout-uri, sarcini în fundal prin beginBackgroundTask, WorkManager și Service, precum și cele mai bune practici pentru procesarea corectă a Background.

Principalele puncte

  • Background — aplicația nu este vizibilă utilizatorului, dar poate executa cod pentru o perioadă limitată de timp
  • iOS background task — beginBackgroundTask(expirationHandler:) oferă până la 30 de secunde pentru finalizarea lucrului
  • Android Service — Foreground Service cu notificare pentru operațiuni lungi în fundal
  • WorkManager — API recomandat pentru sarcini în fundal pe Android cu garanție de execuție
  • Restricții — ambele platforme înăspresc regulile de lucru în fundal pentru economisirea bateriei

Background — noțiunile de bază ale stării de fundal

Background — starea aplicației în care aceasta continuă să existe în sistemul de operare, să execute cod și să consume resurse, dar nu este afișată pe ecranul dispozitivului. Utilizatorul se află pe Ecranul de pornire, într-o altă aplicație sau ecranul dispozitivului este blocat. Pe iOS Background urmează după Inactive — lanțul de tranziție: Active → Inactive → Background. Pe Android onStop semnalează trecerea Activity în Background.

Ambele platforme impun restricții stricte asupra lucrului în fundal. iOS oferă o fereastră limitată (de obicei 30 de secunde) pentru executarea codului după trecerea în Background, după care aplicația este trecută în Suspended. Android este mai flexibil: Foreground Service cu notificare vizibilă poate funcționa nelimitat, dar Background Service obișnuit este limitat la câteva minute. Sarcina cheie a dezvoltatorului — să salveze corect starea și să planifice continuarea lucrului prin API-urile sistemice de sarcini în fundal.

Sistemul poate termina aplicația în fundal în orice moment când memoria este insuficientă. La terminare, toate datele nesalvate se pierd. De aceea este critic să salvați starea în applicationDidEnterBackground (iOS) sau onStop (Android). După terminare, la următoarea pornire aplicația pornește din Not Running cu un start la rece și restabilește starea salvată.

Background vs Suspended

Este important să distingeți Background și Suspended. Background — aplicația execută activ cod. Suspended — aplicația se află în memorie, dar nu execută cod — este înghețată. Pe iOS aplicația trece din Background în Suspended după finalizarea sarcinilor în fundal. Pe Android nu există Suspended — procesul fie există (inclusiv în fundal), fie este terminat (Not Running). Totuși, Android poate suspenda execuția thread-urilor prin LMK (Low Memory Killer).

CaracteristicăiOS BackgroundAndroid Background
Codul se executăDa, până la 30 de secundeDa, depinde de API
UI vizibilNuNu
Timeout implicit~30 sec (beginBackgroundTask)Câteva minute (Service)
Lucru nelimitatDoar categorii speciale (audio, VoIP, navigație)Foreground Service cu notificare
Garanție de execuțieNu — sistemul poate termina oricândWorkManager garantează execuția
Necesită permisiuneDa — capabilities în Info.plistDa — permisiunea FOREGROUND_SERVICE
Starea următoareSuspended → Not RunningNot Running (sau restart)

Background în iOS: Swift, beginBackgroundTask și BGTaskScheduler

În iOS Background este gestionat prin metoda delegat applicationDidEnterBackground. În această metodă, dezvoltatorul trebuie să salveze starea utilizatorului, să elibereze resursele și să finalizeze sarcinile în fundal. Pentru executarea codului după trecerea în Background se folosește beginBackgroundTask(expirationHandler:) — API care solicită sistemului timp suplimentar (de obicei 30 de secunde). Dacă sarcina nu se finalizează în acest timp, expirationHandler este apelat, iar aplicația este trecută forțat în Suspended.

Începând cu iOS 13, Apple a introdus BGTaskScheduler — un API modern pentru planificarea sarcinilor în fundal. Spre deosebire de beginBackgroundTask, care oferă timp doar pentru finalizare după trecerea în fundal, BGTaskScheduler permite planificarea executării sarcinilor în viitor — de exemplu, actualizarea conținutului o dată pe oră sau încărcarea analiticelor noaptea. BGTaskScheduler este abordarea recomandată pentru proiecte noi, deoarece este mai eficient din punct de vedere al bateriei.

swift
import UIKit
import BackgroundTasks

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

    // Aplicația a intrat în fundal — începem sarcina în fundal
    func applicationDidEnterBackground(_ application: UIApplication) {
        saveAppState()
        startBackgroundTask()
    }

    private func startBackgroundTask() {
        backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in
            // Timpul a expirat — forțăm finalizarea
            self?.endBackgroundTask()
        }

        // Simulăm lucrul în fundal (salvarea datelor pe server)
        DispatchQueue.global().async { [weak self] in
            uploadAnalyticsData()
            self?.endBackgroundTask()
        }
    }

    private func endBackgroundTask() {
        guard backgroundTaskID != .invalid else { return }
        UIApplication.shared.endBackgroundTask(backgroundTaskID)
        backgroundTaskID = .invalid
    }

    // Înregistrare BGTaskScheduler
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        BGTaskScheduler.shared.register(
            forTaskWithIdentifier: "com.example.refresh",
            using: nil
        ) { task in
            handleAppRefresh(task: task as! BGAppRefreshTask)
        }
        return true
    }

    func scheduleAppRefresh() {
        let request = BGAppRefreshTaskRequest(identifier: "com.example.refresh")
        request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
        try? BGTaskScheduler.shared.submit(request)
    }

    func handleAppRefresh(task: BGAppRefreshTask) {
        scheduleAppRefresh()
        task.expirationHandler = { task.setTaskCompleted(success: false) }
        fetchLatestData { result in
            task.setTaskCompleted(success: result)
        }
    }
}

Codul arată gestionarea completă a Background pe iOS. applicationDidEnterBackground pornește o sarcină în fundal prin beginBackgroundTask cu timeout și expirationHandler. În paralel, BGTaskScheduler este înregistrat pentru actualizarea periodică a conținutului. beginBackgroundTask este folosit pentru finalizarea imediată a lucrului, BGTaskScheduler — pentru planificarea pe termen lung. Ambele API necesită gestionarea corectă a identificatorilor de sarcini.

Background în Android: Kotlin, Service, WorkManager

În Android Background este gestionat prin mai multe API-uri. Service tradițional permite executarea codului în fundal, dar din Android 8+ (API 26) Background Service este limitat: sistemul îl termină la câteva minute după ce aplicația trece în fundal. Foreground Service cu notificare permanentă poate funcționa nelimitat. WorkManager — soluția recomandată pentru sarcini în fundal cu garanție de execuție chiar și după repornirea dispozitivului.

Android, spre deosebire de iOS, suportă procese de fundal de lungă durată. Foreground Service este folosit pentru sarcini pe care utilizatorul trebuie să le vadă — redarea muzicii, navigația, înregistrarea antrenamentului. JobScheduler și WorkManager — pentru sarcini care pot fi amânate: sincronizarea datelor, încărcarea logurilor, actualizarea cache-ului. Diferența cheie: Android permite planificarea sarcinilor cu condiții — Wi-Fi, încărcare, inactivitatea dispozitivului, ceea ce economisește bateria și traficul.

kotlin
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.work.*

// 1. Foreground Service pentru lucru lung în fundal
class SyncService : Service() {

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notification = createNotification()
        startForeground(NOTIFICATION_ID, notification)
        performBackgroundWork()
        return START_STICKY
    }

    private fun performBackgroundWork() {
        Thread {
            // Sincronizarea datelor cu serverul
            syncDataToServer()
            stopForeground(STOP_FOREGROUND_REMOVE)
            stopSelf()
        }.start()
    }

    override fun onBind(intent: Intent?): IBinder? = null
}

// 2. WorkManager pentru sarcini amânate în fundal
class DataSyncWorker(
    private val context: Context,
    private val params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        return try {
            // Încărcarea analiticelor pe server
            uploadAnalytics()
            Result.success()
        } catch (e: Exception) {
            if (runAttemptCount < 3) Result.retry() else Result.failure()
        }
    }
}

// Planificarea sarcinii WorkManager
fun scheduleBackgroundSync(context: Context) {
    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .setRequiresBatteryNotLow(true)
        .build()

    val request = OneTimeWorkRequestBuilder<DataSyncWorker>()
        .setConstraints(constraints)
        .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
        .build()

    WorkManager.getInstance(context).enqueue(request)
}

Codul arată două abordări pentru lucrul în fundal pe Android. SyncService — Foreground Service cu notificare pentru lucru imediat și lung în fundal. DataSyncWorker — WorkManager pentru sarcini amânate cu condiții (Wi-Fi, încărcare). WorkManager garantează execuția chiar și după repornirea dispozitivului și suportă exponential backoff pentru reîncercări. Foreground Service necesită o notificare permanentă în bara de status.

Restricțiile lucrului în fundal pe iOS și Android

Ambele platforme mobile înăspresc constant regulile de lucru în fundal. Pe iOS fiecare nouă generație de sistem de operare reduce timpul de lucru în fundal și adaugă restricții noi. Pe Android Google introduce moduri de economisire a energiei din ce în ce mai stricte (Doze, App Standby). Dezvoltatorul trebuie să fie la curent cu restricțiile actuale pentru ca aplicația să nu fie terminată prematur de sistem.

Pe iOS, începând cu iOS 13, sistemul dezactivează sarcinile în fundal pentru aplicațiile care abuzează de timpul în fundal. Fiecare aplicație primește limite specifice bazate pe comportamentul utilizatorului. BGTaskScheduler planifică execuția la momentul optim — de exemplu, când dispozitivul este conectat la Wi-Fi și se încarcă. Aplicațiile care folosesc corect BGTaskScheduler primesc mai mult timp în fundal.

Pe Android, începând cu Android 9 (API 28), lucrul în fundal este limitat de modul Doze, care se activează la inactivitatea dispozitivului. Aplicațiile în Doze nu pot executa sarcini în fundal, rețeaua este dezactivată, JobScheduler și WorkManager amână sarcinile până la ieșirea din Doze. Foreground Service este singura modalitate de a ocoli Doze, dar abuzul duce la blocarea aplicației de către utilizator și eliminarea permisiunilor.

RestricțieiOSAndroid
Timeout sarcină în fundal~30 secunde (beginBackgroundTask)Câteva minute (JobScheduler)
Fundal nelimitatAudio, VoIP, navigație, BluetoothForeground Service + notificare
Economisire energieLow Power Mode — dezactivează sarcinile în fundalDoze, App Standby, Battery Optimization
PlanificareBGTaskScheduler (iOS 13+)WorkManager (Android Jetpack)
După repornireDoar notificare pushWorkManager păstrează sarcinile
Timp max. de execuție~30 minute (audio)Nelimitat (Foreground Service)

Cele mai bune practici pentru lucrul în fundal

Prima regulă — minimizați consumul de resurse în fundal. Majoritatea sarcinilor în fundal pot fi amânate pentru momentul când dispozitivul se încarcă și este conectat la Wi-Fi. Folosiți BGTaskScheduler (iOS) și WorkManager (Android) pentru planificarea sarcinilor cu condiții. Nu rulați calcule grele în fundal — acest lucru descarcă bateria și duce la throttling-ul CPU.

A doua regulă — specificați întotdeauna expirationHandler pentru beginBackgroundTask. Dacă aplicația nu finalizează sarcina în timpul alocat, sistemul o va trece forțat în Suspended sau o va termina. ExpirationHandler este ultima șansă de a salva datele și de a finaliza corect lucrul. Pe Android folosiți setForegroundAsync în WorkManager pentru a transforma o sarcină obișnuită în foreground, dacă este necesar mai mult timp.

A treia regulă — verificați restricțiile de lucru în fundal înainte de pornire. Pe iOS folosiți UIApplication.shared.backgroundTimeRemaining pentru a verifica timpul rămas. Pe Android verificați ActivityManager.isBackgroundRestricted() — dacă este true, aplicația nu va putea rula sarcini în fundal și trebuie să sugerați utilizatorului să elimine restricțiile în setări. Acest lucru este deosebit de important pentru aplicațiile cu funcții critice în fundal — ceasuri deșteptătoare, calendare, sincronizare.

A patra regulă — testați sarcinile în fundal pe un dispozitiv real. Simulatorul și emulatorul nu reproduc restricțiile reale de lucru în fundal. Pe iOS folosiți Debug → Simulate Background Fetch în Xcode. Pe Android — adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED pentru testarea WorkManager după repornire. Testele reale pe un dispozitiv cu baterie scăzută dezvăluie majoritatea problemelor de lucru în fundal.

swift
import UIKit

final class BackgroundTaskManager {
    static let shared = BackgroundTaskManager()
    private var tasks: [String: UIBackgroundTaskIdentifier] = [:]

    func startTask(name: String, expiration: @escaping () -> Void) {
        let remaining = UIApplication.shared.backgroundTimeRemaining
        print("Timp rămas în fundal: \(remaining) sec")

        let task = UIApplication.shared.beginBackgroundTask { [weak self] in
            print("Timpul a expirat pentru sarcina: \(name)")
            expiration()
            self?.endTask(name: name)
        }

        tasks[name] = task
    }

    func endTask(name: String) {
        guard let task = tasks.removeValue(forKey: name),
              task != .invalid
        else { return }
        UIApplication.shared.endBackgroundTask(task)
    }
}

Codul arată un manager de sarcini în fundal care urmărește timpul rămas și gestionează identificatorii. backgroundTimeRemaining returnează numărul de secunde până la terminarea forțată — dacă valoarea este infinită, aplicația funcționează fără restricții (audio, navigație). Managerul permite rularea mai multor sarcini în fundal cu nume diferite și finalizarea corectă a fiecăreia. Această abordare previne scurgerea sarcinilor în fundal și garantează că sistemul nu va termina aplicația din cauza sarcinilor neînchise.

Întrebări frecvente

Poate o aplicație iOS să ruleze în fundal la nesfârșit?

Da, pentru un număr limitat de categorii: audio (AVAudioSession categoria .playback), VoIP (PushKit), navigație (CLLocationManager cu allowsBackgroundLocationUpdates), Bluetooth (mod fundal central), actualizare în fundal (BGTaskScheduler). Pentru toate celelalte — maximum 30 de secunde. În iOS 16+ Apple a înăsprit cerințele chiar și pentru categoriile permise.

Cu ce diferă beginBackgroundTask de BGTaskScheduler?

beginBackgroundTask — API sincron pentru prelungirea vieții aplicației cu ~30 de secunde după trecerea în fundal. Se apelează în applicationDidEnterBackground. BGTaskScheduler — API asincron pentru planificarea sarcinilor în viitor prin declanșatoare sistemice (timp, locație, actualizare conținut). BGTaskScheduler este abordarea modernă recomandată de Apple pentru iOS 13+.

De ce Android îmi ucide Background Service-ul?

Începând cu Android 8 (API 26), Background Service este terminat la câteva minute după ce aplicația trece în fundal. Soluție: folosiți Foreground Service cu notificare pentru operații lungi sau WorkManager pentru sarcini amânate. Verificați Battery Optimization pentru aplicația dvs. în setări — dacă este optimizată, sistemul poate amâna sau anula sarcinile în fundal.

Cum să testez Background pe simulatorul iOS?

Apăsați Cmd+Shift+H pentru a trece la ecranul de pornire. În Xcode folosiți Debug → Simulate Background Fetch. Pentru a verifica beginBackgroundTask deschideți consola (Shift+Cmd+C) și apelați e UIApplication.shared.backgroundTimeRemaining. În Xcode 15+ este disponibil scenariul Background Execution în fila Diagnostics a simulatorului.

Ce este process death pe Android?

Process Death — terminarea procesului Android de către sistem la insuficiență de resurse sau la inactivitate în fundal. Spre deosebire de iOS, Android nu are Suspended — procesul fie este viu (poate fi în fundal), fie este mort (Not Running). Process Death este un comportament normal al sistemului de operare, iar aplicația trebuie să restabilească corect starea după acesta prin SavedStateHandle, onSaveInstanceState sau DataStore.

Rezumat

  • Background — aplicația nu este vizibilă pe ecran, dar execută cod, spre deosebire de Suspended (înghețată)
  • iOS — beginBackgroundTask (până la 30 sec) și BGTaskScheduler pentru planificarea sarcinilor viitoare
  • Android — Foreground Service pentru operații lungi, WorkManager pentru sarcini amânate cu garanție
  • Restricții — ambele platforme înăspresc regulile de lucru în fundal: Doze, Low Power Mode, App Standby
  • Salvare — applicationDidEnterBackground și onStop — ultima șansă de a salva datele înainte de Suspended/Not Running
  • Planificare — BGTaskScheduler și WorkManager funcționează cu condiții (Wi-Fi, încărcare, timp)
  • Foreground Service — singura modalitate de lucru nelimitat în fundal pe ambele platforme

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