Background: основе, рад апликације у позадини на iOS и Android

Аутор: IT Sectr Објављено: 2026-03-03 Време читања: 10 мин

Background — стање животног циклуса апликације у којем она наставља да се извршава, али се не приказује на екрану. Објашњавамо основе позадинског рада на iOS и Android: ограничења, тајмауте, позадинске задатке путем beginBackgroundTask, WorkManager и Service, као и најбоље праксе за коректну обраду Background.

Главно

  • Background — апликација није видљива кориснику, али може извршавати код током ограниченог времена
  • iOS background task — beginBackgroundTask(expirationHandler:) даје до 30 секунди за завршетак рада
  • Android Service — Foreground Service са обавештењем за дуге позадинске операције
  • WorkManager — препоручени API за позадинске задатке на Android-у са гаранцијом извршења
  • Ограничења — обе платформе пооштравају правила позадинског рада ради уштеде батерије

Background — основе позадинског стања

Background — стање апликације у којем она наставља да постоји у оперативном систему, извршава код и троши ресурсе, али се не приказује на екрану уређаја. Корисник се налази на почетном екрану, у другој апликацији или је екран уређаја закључан. На iOS-у Background следи након Inactive — ланац преласка: Active → Inactive → Background. На Android-у onStop сигнализира прелазак Activity у Background.

Обе платформе постављају строга ограничења на позадински рад. iOS обезбеђује ограничен прозор (обично 30 секунди) за извршавање кода након одласка у Background, након чега апликација прелази у Suspended. Android је флексибилнији: Foreground Service са видљивим обавештењем може радити неограничено, али обични Background Service је ограничен на неколико минута. Кључни задатак програмера — правилно сачувати стање и планирати наставак рада путем системских API-ја позадинских задатака.

Систем може прекинути позадинску апликацију у било ком тренутку при недостатку меморије. При прекиду сви несачувани подаци се губе. Зато је критично важно сачувати стање у applicationDidEnterBackground (iOS) или onStop (Android). Након прекида, при следећем покретању апликација стартује из Not Running са хладним стартом и враћа сачувано стање.

Background vs Suspended

Важно је разликовати Background и Suspended. Background — апликација активно извршава код. Suspended — апликација се налази у меморији, али не извршава код — замрзнута је. На iOS-у апликација прелази из Background у Suspended након завршетка позадинских задатака. На Android-у нема Suspended — процес или постоји (укључујући позадину) или је прекинут (Not Running). Међутим, Android може зауставити извршење нити путем LMK (Low Memory Killer).

КарактеристикаiOS BackgroundAndroid Background
Код се извршаваДа, до 30 секундиДа, зависи од API-ја
UI видљивНеНе
Подразумевани тајмаут~30 сек (beginBackgroundTask)Неколико минута (Service)
Неограничен радСамо посебне категорије (аудио, VoIP, навигација)Foreground Service са обавештењем
Гаранција извршењаНе — систем може прекинути у било ком тренуткуWorkManager гарантује извршење
Потребна дозволаДа — capabilities у Info.plistДа — FOREGROUND_SERVICE дозвола
Следеће стањеSuspended → Not RunningNot Running (или рестарт)

Background на iOS-у: Swift, beginBackgroundTask и BGTaskScheduler

На iOS-у Background се обрађује путем метода делегата applicationDidEnterBackground. У овом методу програмер треба да сачува стање корисника, ослободи ресурсе и заврши позадинске задатке. За извршавање кода након одласка у Background користи се beginBackgroundTask(expirationHandler:) — API који захтева од система додатно време (обично 30 секунди). Ако се задатак не заврши у овом времену, позива се expirationHandler и апликација се принудно пребацује у Suspended.

Од iOS 13, Apple је представио BGTaskScheduler — модеран API за планирање позадинских задатака. За разлику од beginBackgroundTask, који даје време само за завршетак након одласка у позадину, BGTaskScheduler омогућава планирање извршења задатака у будућности — на пример, ажурирање садржаја једном на сат или отпремање аналитике ноћу. BGTaskScheduler је препоручени приступ за нове пројекте, јер је ефикаснији у погледу батерије.

swift
import UIKit
import BackgroundTasks

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

    // Апликација је отишла у позадину — почињемо позадински задатак
    func applicationDidEnterBackground(_ application: UIApplication) {
        saveAppState()
        startBackgroundTask()
    }

    private func startBackgroundTask() {
        backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in
            // Време је истекло — принудно завршавамо
            self?.endBackgroundTask()
        }

        // Симулирамо позадински рад (чување података на сервер)
        DispatchQueue.global().async { [weak self] in
            uploadAnalyticsData()
            self?.endBackgroundTask()
        }
    }

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

    // Регистрација 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)
        }
    }
}

Код приказује потпуну обраду Background на iOS-у. applicationDidEnterBackground покреће позадински задатак путем beginBackgroundTask са тајмаутом и expirationHandler. Паралелно се региструје BGTaskScheduler за периодично ажурирање садржаја. beginBackgroundTask се користи за тренутни завршетак рада, BGTaskScheduler — за дугорочно планирање. Оба API-ја захтевају правилно управљање идентификаторима задатака.

Background на Android-у: Kotlin, Service, WorkManager

На Android-у Background се управља путем неколико API-ја. Традиционални Service омогућава извршавање кода у позадини, али од Android 8+ (API 26) Background Service је ограничен: систем га прекида неколико минута након одласка апликације у позадину. Foreground Service са сталним обавештењем може радити неограничено. WorkManager — препоручено решење за позадинске задатке са гаранцијом извршења чак и након поновног покретања уређаја.

Android, за разлику од iOS-а, подржава дуготрајне позадинске процесе. Foreground Service се користи за задатке које корисник треба да види — репродукција музике, навигација, снимање тренинга. JobScheduler и WorkManager — за задатке који могу бити одложени: синхронизација података, отпремање логова, ажурирање кеша. Кључна разлика: Android омогућава планирање задатака са условима — Wi-Fi, пуњење, неактивност уређаја, што штеди батерију и саобраћај.

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

// 1. Foreground Service за дуг позадински рад
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 {
            // Синхронизација података са сервером
            syncDataToServer()
            stopForeground(STOP_FOREGROUND_REMOVE)
            stopSelf()
        }.start()
    }

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

// 2. WorkManager за одложене позадинске задатке
class DataSyncWorker(
    private val context: Context,
    private val params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        return try {
            // Отпремање аналитике на сервер
            uploadAnalytics()
            Result.success()
        } catch (e: Exception) {
            if (runAttemptCount < 3) Result.retry() else Result.failure()
        }
    }
}

// Планирање 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)
}

Код приказује два приступа позадинском раду на Android-у. SyncService — Foreground Service са обавештењем за тренутни и дуготрајни позадински рад. DataSyncWorker — WorkManager за одложене задатке са условима (Wi-Fi, пуњење). WorkManager гарантује извршење чак и након поновног покретања уређаја и подржава exponential backoff за поновне покушаје. Foreground Service захтева стално обавештење у статусној траци.

Ограничења позадинског рада на iOS и Android

Обе мобилне платформе стално пооштравају правила позадинског рада. На iOS-у свака нова генерација ОС-а скраћује време рада у позадини и додаје нова ограничења. На Android-у Google уводи све строже режиме уштеде енергије (Doze, App Standby). Програмер мора бити у току са актуелним ограничењима како апликација не би била прекинута од стране система пре времена.

На iOS-у, почев од iOS 13, систем искључује позадинске задатке за апликације које злоупотребљавају позадинско време. Свака апликација добија одређена ограничења на основу понашања корисника. BGTaskScheduler планира извршење у оптимално време — на пример, када је уређај повезан на Wi-Fi и пуни се. Апликације које правилно користе BGTaskScheduler добијају више позадинског времена.

На Android-у почев од Android 9 (API 28) позадински рад је ограничен режимом Doze, који се активира при неактивности уређаја. Апликације у Doze-у не могу извршавати позадинске задатке, мрежа се искључује, JobScheduler и WorkManager одлажу задатке до изласка из Doze-а. Foreground Service је једини начин да се заобиђе Doze, али злоупотреба доводи до блокирања апликације од стране корисника и уклањања дозвола.

ОграничењеiOSAndroid
Тајмаут позадинског задатка~30 секунди (beginBackgroundTask)Неколико минута (JobScheduler)
Неограничена позадинаАудио, VoIP, навигација, BluetoothForeground Service + обавештење
Уштеда енергијеLow Power Mode — искључује позадинске задаткеDoze, App Standby, Battery Optimization
ПланирањеBGTaskScheduler (iOS 13+)WorkManager (Android Jetpack)
Након поновног покретањаСамо push обавештењеWorkManager чува задатке
Макс. време извршења~30 минута (аудио)Неограничено (Foreground Service)

Најбоље праксе позадинског рада

Прво правило — минимизирајте потрошњу ресурса у позадини. Већину позадинских задатака можете одложити за време када се уређај пуни и повезан је на Wi-Fi. Користите BGTaskScheduler (iOS) и WorkManager (Android) за планирање задатака са условима. Не покрећите тешка израчунавања у позадини — то празни батерију и доводи до throttling-а CPU-а.

Друго правило — увек наведите expirationHandler за beginBackgroundTask. Ако апликација не заврши задатак у предвиђеном времену, систем ће је принудно пребацити у Suspended или прекинути. ExpirationHandler је последња шанса да сачувате податке и правилно завршите рад. На Android-у користите setForegroundAsync у WorkManager-у за претварање обичног задатка у foreground, ако је потребно више времена.

Треће правило — проверавајте ограничења позадинског рада пре покретања. На iOS-у користите UIApplication.shared.backgroundTimeRemaining за проверу преосталог времена. На Android-у проверите ActivityManager.isBackgroundRestricted() — ако је true, апликација неће моћи да покреће позадинске задатке и треба предложити кориснику да уклони ограничења у подешавањима. Ово је посебно важно за апликације са критичним позадинским функцијама — будилници, календари, синхронизација.

Четврто правило — тестирајте позадинске задатке на стварном уређају. Симулатор и емулатор не репродукују стварна ограничења позадинског рада. На iOS-у користите Debug → Simulate Background Fetch у Xcode-у. На Android-у — adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED за тестирање WorkManager-а након поновног покретања. Стварни тестови на уређају са ниским нивоом батерије откривају већину проблема позадинског рада.

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("Преостало времена у позадини: \(remaining) сек")

        let task = UIApplication.shared.beginBackgroundTask { [weak self] in
            print("Време је истекло за задатак: \(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)
    }
}

Код приказује менаџера позадинских задатака који прати преостало време и управља идентификаторима. backgroundTimeRemaining враћа број секунди до принудног прекида — ако је вредност бесконачна, апликација ради без ограничења (аудио, навигација). Менаџер омогућава покретање више позадинских задатака са различитим именима и правилно завршавање сваког. Овакав приступ спречава цурење позадинских задатака и гарантује да систем неће прекинути апликацију због незатворених задатака.

Често постављана питања

Може ли iOS апликација радити у позадини вечно?

Да, за ограничен број категорија: аудио (AVAudioSession категорија .playback), VoIP (PushKit), навигација (CLLocationManager са allowsBackgroundLocationUpdates), Bluetooth (central background mode), позадинско ажурирање (BGTaskScheduler). За све остале — максимално 30 секунди. У iOS 16+ Apple је пооштрила захтеве чак и за дозвољене категорије.

По чему се beginBackgroundTask разликује од BGTaskScheduler-а?

beginBackgroundTask — синхрони API за продужење живота апликације на ~30 секунди након одласка у позадину. Позива се у applicationDidEnterBackground. BGTaskScheduler — асинхрони API за планирање задатака у будућности путем системских окидача (време, локација, ажурирање садржаја). BGTaskScheduler је модеран приступ који Apple препоручује за iOS 13+.

Зашто Android убија мој Background Service?

Почев од Android 8 (API 26), Background Service се прекида неколико минута након одласка апликације у позадину. Решење: користите Foreground Service са обавештењем за дуге операције или WorkManager за одложене задатке. Проверите Battery Optimization за вашу апликацију у подешавањима — ако је оптимизована, систем може одложити или отказати позадинске задатке.

Како тестирати Background на iOS симулатору?

Притисните Cmd+Shift+H за прелазак на почетни екран. У Xcode-у користите Debug → Simulate Background Fetch. За проверу beginBackgroundTask отворите конзолу (Shift+Cmd+C) и позовите e UIApplication.shared.backgroundTimeRemaining. У Xcode 15+ доступан је Background Execution сценарио у Diagnostics картици симулатора.

Шта је process death на Android-у?

Process Death — прекид Android процеса од стране система при недостатку ресурса или при неактивности у позадини. За разлику од iOS-а, Android нема Suspended — процес или постоји (може бити у позадини) или је мртав (Not Running). Process Death је нормално понашање ОС-а и апликација треба правилно да врати стање након њега путем SavedStateHandle, onSaveInstanceState или DataStore-а.

Резиме

  • Background — апликација није видљива на екрану, али извршава код, за разлику од Suspended (замрзнута)
  • iOS — beginBackgroundTask (до 30 сек) и BGTaskScheduler за планирање будућих задатака
  • Android — Foreground Service за дуге операције, WorkManager за одложене задатке са гаранцијом
  • Ограничења — обе платформе пооштравају правила позадинског рада: Doze, Low Power Mode, App Standby
  • Чување — applicationDidEnterBackground и onStop — последња шанса да сачувате податке пре Suspended/Not Running
  • Планирање — BGTaskScheduler и WorkManager раде са условима (Wi-Fi, пуњење, време)
  • Foreground Service — једини начин неограниченог позадинског рада на обе платформе

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође