Background — az alkalmazás életciklusának az az állapota, amelyben tovább fut, de nem jelenik meg a képernyőn. Elmagyarázzuk a háttérben végzett munka alapjait iOS és Android rendszeren: korlátozások, időtúllépések, háttérfeladatok beginBackgroundTask, WorkManager és Service segítségével, valamint a legjobb gyakorlatok a Background helyes kezeléséhez.
Főbb pontok
Background — az alkalmazás állapota, amelyben továbbra is létezik az operációs rendszerben, kódot hajt végre és erőforrásokat fogyaszt, de nem jelenik meg a készülék képernyőjén. A felhasználó a kezdőképernyőn van, egy másik alkalmazásban, vagy a készülék képernyője zárolva van. iOS rendszeren a Background az Inactive után következik — az átmenet láncolata: Active → Inactive → Background. Android rendszeren az onStop jelzi az Activity Backgroundba való átmenetét.
Mindkét platform szigorú korlátozásokat ír elő a háttérmunkára. IOS egy korlátozott időablakot (általában 30 másodperc) biztosít a kód végrehajtására a Backgroundba kerülés után, ezután az alkalmazás Suspended állapotba kerül. Az Android rugalmasabb: a Foreground Service látható értesítéssel korlátlanul működhet, de a szokásos Background Service néhány percre korlátozott. A fejlesztő kulcsfeladata — az állapot helyes mentése és a munka folytatásának ütemezése a rendszer háttérfeladat API-jain keresztül.
A rendszer bármikor megszüntetheti a háttéralkalmazást, ha nincs elegendő memória. A megszüntetéskor minden nem mentett adat elveszik. Ezért kritikus fontosságú az állapot mentése az applicationDidEnterBackground (iOS) vagy onStop (Android) metódusban. A megszüntetés után a következő indításkor az alkalmazás a Not Running állapotból indul hideg indítással, és visszaállítja a mentett állapotot.
Fontos megkülönböztetni a Background és Suspended állapotot. Background — az alkalmazás aktívan kódot hajt végre. Suspended — az alkalmazás a memóriában van, de nem hajt végre kódot — le van fagyasztva. IOS rendszeren az alkalmazás a háttérfeladatok befejezése után Backgroundból Suspendedbe kerül. Android rendszeren nincs Suspended — a folyamat vagy létezik (beleértve a hátteret), vagy megszűnt (Not Running). Az Android azonban felfüggesztheti a szálak végrehajtását az LMK (Low Memory Killer) segítségével.
| Jellemző | iOS Background | Android Background |
|---|---|---|
| Kód végrehajtása | Igen, akár 30 másodpercig | Igen, API-tól függ |
| UI látható | Nem | Nem |
| Alapértelmezett időtúllépés | ~30 mp (beginBackgroundTask) | Néhány perc (Service) |
| Korlátlan munka | Csak speciális kategóriák (audio, VoIP, navigáció) | Foreground Service értesítéssel |
| Végrehajtási garancia | Nem — a rendszer bármikor megszüntetheti | A WorkManager garantálja a végrehajtást |
| Engedély szükséges | Igen — capabilities az Info.plist-ben | Igen — FOREGROUND_SERVICE engedély |
| Következő állapot | Suspended → Not Running | Not Running (vagy újraindítás) |
IOS rendszeren a Background az applicationDidEnterBackground delegált metóduson keresztül kerül feldolgozásra. Ebben a metódusban a fejlesztőnek el kell mentenie a felhasználó állapotát, fel kell szabadítania az erőforrásokat és be kell fejeznie a háttérfeladatokat. A Backgroundba kerülés utáni kódvégrehajtáshoz a beginBackgroundTask(expirationHandler:) használatos — egy API, amely további időt (általában 30 másodpercet) kér a rendszertől. Ha a feladat nem fejeződik be ezen idő alatt, az expirationHandler meghívódik, és az alkalmazás kényszerítve Suspended állapotba kerül.
Az iOS 13-tól kezdve az Apple bevezette a BGTaskScheduler-t — egy modern API-t a háttérfeladatok ütemezéséhez. Ellentétben a beginBackgroundTask-val, amely csak a háttérbe kerülés utáni befejezéshez ad időt, a BGTaskScheduler lehetővé teszi a feladatok jövőbeli végrehajtásának ütemezését — például a tartalom óránkénti frissítését vagy az analitika éjszakai feltöltését. A BGTaskScheduler az ajánlott megközelítés az új projektekhez, mivel akkumulátor szempontjából hatékonyabb.
import UIKit
import BackgroundTasks
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
// Az alkalmazás háttérbe került — elindítjuk a háttérfeladatot
func applicationDidEnterBackground(_ application: UIApplication) {
saveAppState()
startBackgroundTask()
}
private func startBackgroundTask() {
backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in
// Az idő lejárt — kényszerítve befejezzük
self?.endBackgroundTask()
}
// Szimuláljuk a háttérmunkát (adatok mentése a szerverre)
DispatchQueue.global().async { [weak self] in
uploadAnalyticsData()
self?.endBackgroundTask()
}
}
private func endBackgroundTask() {
guard backgroundTaskID != .invalid else { return }
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
// BGTaskScheduler regisztrálása
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)
}
}
}A kód a Background teljes feldolgozását mutatja iOS rendszeren. applicationDidEnterBackground elindít egy háttérfeladatot a beginBackgroundTask segítségével időtúllépéssel és expirationHandler-rel. Ezzel párhuzamosan a BGTaskScheduler regisztrálásra kerül az időszakos tartalomfrissítéshez. A beginBackgroundTask a munka azonnali befejezésére szolgál, a BGTaskScheduler — a hosszú távú ütemezésre. Mindkét API megköveteli a feladatazonosítók helyes kezelését.
Android rendszeren a Background több API-n keresztül kerül kezelésre. A hagyományos Service lehetővé teszi a kód háttérben való végrehajtását, de Android 8+ (API 26) óta a Background Service korlátozott: a rendszer néhány perccel az alkalmazás háttérbe kerülése után megszünteti. A Foreground Service állandó értesítéssel korlátlanul működhet. WorkManager — az ajánlott megoldás a háttérfeladatokhoz végrehajtási garanciával, még a készülék újraindítása után is.
Az Android az iOS-szel ellentétben támogatja a hosszú életű háttérfolyamatokat. A Foreground Service olyan feladatokhoz használatos, amelyeket a felhasználónak látnia kell — zenelejátszás, navigáció, edzés rögzítése. A JobScheduler és WorkManager — olyan feladatokhoz, amelyek elhalaszthatók: adatszinkronizáció, naplók feltöltése, gyorsítótár frissítése. A kulcsfontosságú különbség: az Android lehetővé teszi a feladatok feltételekkel történő ütemezését — Wi-Fi, töltés, a készülék inaktivitása, ami akkumulátort és adatforgalmat takarít meg.
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.work.*
// 1. Foreground Service hosszú háttérmunkához
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 {
// Adatok szinkronizálása a szerverrel
syncDataToServer()
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()
}.start()
}
override fun onBind(intent: Intent?): IBinder? = null
}
// 2. WorkManager elhalasztott háttérfeladatokhoz
class DataSyncWorker(
private val context: Context,
private val params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
// Analitika feltöltése a szerverre
uploadAnalytics()
Result.success()
} catch (e: Exception) {
if (runAttemptCount < 3) Result.retry() else Result.failure()
}
}
}
// WorkManager feladat ütemezése
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)
}A kód két megközelítést mutat a háttérmunkához Android rendszeren. SyncService — Foreground Service értesítéssel az azonnali és hosszú háttérmunkához. DataSyncWorker — WorkManager elhalasztott feladatokhoz feltételekkel (Wi-Fi, töltés). A WorkManager garantálja a végrehajtást még a készülék újraindítása után is, és támogatja az exponential backoff-t az újrapróbálkozásokhoz. A Foreground Service állandó értesítést igényel az állapotsorban.
Mindkét mobil platform folyamatosan szigorítja a háttérmunka szabályait. Az iOS minden új operációs rendszer-generációja csökkenti a háttérmunka idejét és új korlátozásokat ad hozzá. Az Androidon a Google egyre szigorúbb energiatakarékos módokat vezet be (Doze, App Standby). A fejlesztőnek ismernie kell az aktuális korlátozásokat, hogy az alkalmazást ne szüntesse meg idő előtt a rendszer.
Az iOS rendszeren az iOS 13-tól kezdve a rendszer kikapcsolja a háttérfeladatokat azoknál az alkalmazásoknál, amelyek visszaélnek a háttéridővel. Minden alkalmazás konkrét korlátokat kap a felhasználói viselkedés alapján. A BGTaskScheduler a végrehajtást az optimális időre ütemezi — például amikor a készülék Wi-Fi-hez csatlakozik és töltődik. Azok az alkalmazások, amelyek helyesen használják a BGTaskScheduler-t, több háttéridőt kapnak.
Android rendszeren az Android 9-től (API 28) kezdve a háttérmunka korlátozva van a Doze mód által, amely a készülék inaktivitásakor aktiválódik. A Doze-ban lévő alkalmazások nem hajthatnak végre háttérfeladatokat, a hálózat kikapcsol, a JobScheduler és WorkManager elhalasztja a feladatokat a Doze-ból való kilépésig. A Foreground Service az egyetlen mód a Doze megkerülésére, de a visszaélés az alkalmazás felhasználó általi blokkolásához és az engedélyek eltávolításához vezet.
| Korlátozás | iOS | Android |
|---|---|---|
| Háttérfeladat időtúllépése | ~30 másodperc (beginBackgroundTask) | Néhány perc (JobScheduler) |
| Korlátlan háttér | Audio, VoIP, navigáció, Bluetooth | Foreground Service + értesítés |
| Energiatakarékosság | Low Power Mode — kikapcsolja a háttérfeladatokat | Doze, App Standby, Battery Optimization |
| Ütemezés | BGTaskScheduler (iOS 13+) | WorkManager (Android Jetpack) |
| Újraindítás után | Csak push értesítés | A WorkManager megőrzi a feladatokat |
| Max. végrehajtási idő | ~30 perc (audio) | Korlátlan (Foreground Service) |
Első szabály — minimalizálja az erőforrás-felhasználást a háttérben. A legtöbb háttérfeladat elhalasztható arra az időre, amikor a készülék töltődik és Wi-Fi-hez csatlakozik. Használja a BGTaskScheduler-t (iOS) és a WorkManager-t (Android) a feladatok feltételekkel történő ütemezéséhez. Ne futtasson nehéz számításokat a háttérben — ez lemeríti az akkumulátort és CPU-throttlinghoz vezet.
Második szabály — mindig adjon meg expirationHandler-t a beginBackgroundTask számára. Ha az alkalmazás nem fejezi be a feladatot a kijelölt időn belül, a rendszer kényszerítve Suspended állapotba helyezi vagy megszünteti. Az expirationHandler az utolsó esély az adatok mentésére és a munka helyes befejezésére. Android rendszeren használja a setForegroundAsync-t a WorkManager-ben a szokásos feladat foreground-dá alakításához, ha több időre van szükség.
Harmadik szabály — ellenőrizze a háttérmunka korlátozásait az indítás előtt. IOS rendszeren használja a UIApplication.shared.backgroundTimeRemaining-t a fennmaradó idő ellenőrzéséhez. Android rendszeren ellenőrizze az ActivityManager.isBackgroundRestricted() értékét — ha true, az alkalmazás nem tud háttérfeladatokat futtatni, és javasolnia kell a felhasználónak a korlátozások eltávolítását a beállításokban. Ez különösen fontos a kritikus háttérfunkciókkal rendelkező alkalmazásoknál — ébresztőórák, naptárak, szinkronizáció.
Negyedik szabály — tesztelje a háttérfeladatokat valós eszközön. A szimulátor és emulátor nem reprodukálja a valós háttérmunka-korlátozásokat. IOS rendszeren használja a Debug → Simulate Background Fetch funkciót az Xcode-ban. Android rendszeren — adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED a WorkManager teszteléséhez újraindítás után. A valós tesztek alacsony akkumulátorszintű eszközön feltárják a háttérmunka problémáinak többségét.
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("Hátralévő idő a háttérben: \(remaining) mp")
let task = UIApplication.shared.beginBackgroundTask { [weak self] in
print("Lejárt az idő a feladathoz: \(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)
}
}A kód egy háttérfeladat-kezelőt mutat, amely nyomon követi a fennmaradó időt és kezeli az azonosítókat. backgroundTimeRemaining visszaadja a kényszerített megszüntetésig hátralévő másodpercek számát — ha az érték végtelen, az alkalmazás korlátozás nélkül működik (audio, navigáció). A kezelő lehetővé teszi több háttérfeladat futtatását különböző nevekkel és mindegyik helyes befejezését. Ez a megközelítés megakadályozza a háttérfeladatok szivárgását, és garantálja, hogy a rendszer nem szünteti meg az alkalmazást a be nem zárt feladatok miatt.
Gyakran ismételt kérdések
Igen, korlátozott számú kategória esetében: audio (AVAudioSession .playback kategória), VoIP (PushKit), navigáció (CLLocationManager allowsBackgroundLocationUpdates paraméterrel), Bluetooth (központi háttérmód), háttérfrissítés (BGTaskScheduler). Minden más esetben — maximum 30 másodperc. Az iOS 16+-ban az Apple szigorította a követelményeket még az engedélyezett kategóriák esetében is.
beginBackgroundTask — szinkron API az alkalmazás élettartamának ~30 másodperccel történő meghosszabbítására a háttérbe kerülés után. Az applicationDidEnterBackground-ben hívódik meg. BGTaskScheduler — aszinkron API a feladatok jövőbeni ütemezésére rendszerindítók (idő, hely, tartalomfrissítés) segítségével. A BGTaskScheduler a modern megközelítés, amelyet az Apple ajánl iOS 13+ rendszerhez.
Az Android 8-tól (API 26) kezdve a Background Service néhány perccel az alkalmazás háttérbe kerülése után megszűnik. Megoldás: használjon Foreground Service-t értesítéssel a hosszú műveletekhez vagy WorkManager-t az elhalasztott feladatokhoz. Ellenőrizze a Battery Optimization-t az alkalmazásához a beállításokban — ha optimalizálva van, a rendszer elhalaszthatja vagy törölheti a háttérfeladatokat.
Nyomja meg a Cmd+Shift+H billentyűket a kezdőképernyőre lépéshez. Az Xcode-ban használja a Debug → Simulate Background Fetch funkciót. A beginBackgroundTask ellenőrzéséhez nyissa meg a konzolt (Shift+Cmd+C), és hívja meg a e UIApplication.shared.backgroundTimeRemaining parancsot. Az Xcode 15+-ban elérhető a Background Execution forgatókönyv a szimulátor Diagnostics lapján.
Process Death — az Android folyamat megszüntetése a rendszer által erőforrás-hiány vagy háttérben való inaktivitás esetén. Az iOS-szel ellentétben az Androidon nincs Suspended — a folyamat vagy él (lehet a háttérben), vagy halott (Not Running). A Process Death az operációs rendszer normál viselkedése, és az alkalmazásnak helyesen kell visszaállítania az állapotot utána a SavedStateHandle, onSaveInstanceState vagy DataStore segítségével.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is