Background é um estado do ciclo de vida do aplicativo no qual ele continua em execução, mas não é exibido na tela. Explicamos os fundamentos do trabalho em segundo plano no iOS e Android: limitações, timeouts, tarefas em segundo plano via beginBackgroundTask, WorkManager e Service, bem como práticas recomendadas para o tratamento correto do Background.
Principais Pontos
Background é um estado do aplicativo no qual ele continua existindo no sistema operacional, executa código e consome recursos, mas não é exibido na tela do dispositivo. O usuário está na Tela Inicial, em outro aplicativo ou a tela do dispositivo está bloqueada. No iOS, Background segue Inactive — a cadeia de transição é: Active → Inactive → Background. No Android, onStop sinaliza a transição de uma Activity para Background.
Ambas as plataformas impõem restrições rigorosas ao trabalho em segundo plano. O iOS fornece uma janela limitada (geralmente 30 segundos) para executar código após entrar em Background, após a qual o aplicativo passa para Suspended. O Android é mais flexível: um Foreground Service com uma notificação visível pode ser executado indefinidamente, mas um Background Service comum é limitado a alguns minutos. A tarefa principal do desenvolvedor é salvar corretamente o estado e agendar a continuação do trabalho através das APIs de tarefas em segundo plano do sistema.
O sistema pode encerrar um aplicativo em segundo plano a qualquer momento quando a memória estiver baixa. Ao encerrar, todos os dados não salvos são perdidos. Portanto, é fundamental salvar o estado em applicationDidEnterBackground (iOS) ou onStop (Android). Após o encerramento, a próxima inicialização começa de Not Running com uma inicialização a frio e restaura o estado salvo.
É importante distinguir Background de Suspended. Background — o aplicativo está executando código ativamente. Suspended — o aplicativo está na memória, mas não executa código — está congelado. No iOS, o aplicativo passa de Background para Suspended após concluir as tarefas em segundo plano. O Android não tem Suspended — o processo existe (incluindo Background) ou é encerrado (Not Running). No entanto, o Android pode pausar a execução de threads via LMK (Low Memory Killer).
| Característica | iOS Background | Android Background |
|---|---|---|
| Código executa | Sim, até 30 segundos | Sim, depende da API |
| UI visível | Não | Não |
| Timeout padrão | ~30 seg (beginBackgroundTask) | Vários minutos (Service) |
| Trabalho ilimitado | Apenas categorias especiais (áudio, VoIP, navegação) | Foreground Service com notificação |
| Garantia de execução | Não — o sistema pode encerrar a qualquer momento | WorkManager garante a execução |
| Permissão necessária | Sim — capabilities no Info.plist | Sim — permissão FOREGROUND_SERVICE |
| Próximo estado | Suspended → Not Running | Not Running (ou reinício) |
No iOS, Background é tratado através do método delegado applicationDidEnterBackground. Neste método, o desenvolvedor deve salvar o estado do usuário, liberar recursos e concluir as tarefas em segundo plano. Para executar código após entrar em Background, usa-se beginBackgroundTask(expirationHandler:) — uma API que solicita tempo adicional ao sistema (geralmente 30 segundos). Se a tarefa não for concluída dentro deste tempo, o expirationHandler é chamado e o aplicativo é forçado a passar para Suspended.
Com o iOS 13, a Apple apresentou o BGTaskScheduler — uma API moderna para agendar tarefas em segundo plano. Ao contrário do beginBackgroundTask, que só dá tempo para finalizar após ir para segundo plano, o BGTaskScheduler permite agendar a execução de tarefas no futuro — por exemplo, atualizar conteúdo uma vez por hora ou enviar análises à noite. BGTaskScheduler é a abordagem recomendada para novos projetos, pois é mais eficiente em termos de bateria.
import UIKit
import BackgroundTasks
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
// O aplicativo foi para segundo plano — iniciando tarefa em segundo plano
func applicationDidEnterBackground(_ application: UIApplication) {
saveAppState()
startBackgroundTask()
}
private func startBackgroundTask() {
backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in
// Tempo esgotado — finalizando forçadamente
self?.endBackgroundTask()
}
// Simulando trabalho em segundo plano (salvando dados no servidor)
DispatchQueue.global().async { [weak self] in
uploadAnalyticsData()
self?.endBackgroundTask()
}
}
private func endBackgroundTask() {
guard backgroundTaskID != .invalid else { return }
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
// Registro do 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)
}
}
}O código mostra o tratamento completo de Background no iOS. applicationDidEnterBackground inicia uma tarefa em segundo plano via beginBackgroundTask com um timeout e expirationHandler. Simultaneamente, o BGTaskScheduler é registrado para atualizações periódicas de conteúdo. beginBackgroundTask é usado para tarefas de encerramento imediato, BGTaskScheduler é usado para planejamento de longo prazo. Ambas as APIs exigem gerenciamento adequado dos identificadores de tarefas.
No Android, Background é gerenciado através de várias APIs. O Service tradicional permite executar código em segundo plano, mas desde o Android 8+ (API 26), o Background Service é limitado: o sistema o encerra alguns minutos após o aplicativo ir para segundo plano. Um Foreground Service com uma notificação persistente pode ser executado indefinidamente. WorkManager é a solução recomendada para tarefas em segundo plano com garantia de execução mesmo após reinicialização do dispositivo.
O Android, ao contrário do iOS, suporta processos em segundo plano de longa duração. Foreground Service é usado para tarefas que o usuário deve ver — reprodução de música, navegação, registro de treinos. JobScheduler e WorkManager são usados para tarefas que podem ser adiadas: sincronização de dados, envio de logs, atualização de cache. A diferença chave: o Android permite agendar tarefas com condições — Wi-Fi, carregamento, inatividade do dispositivo — o que economiza bateria e tráfego.
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.work.*
// 1. Foreground Service para trabalho prolongado em segundo plano
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 {
// Sincronização de dados com o servidor
syncDataToServer()
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()
}.start()
}
override fun onBind(intent: Intent?): IBinder? = null
}
// 2. WorkManager para tarefas adiadas em segundo plano
class DataSyncWorker(
private val context: Context,
private val params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
// Envio de análises para o servidor
uploadAnalytics()
Result.success()
} catch (e: Exception) {
if (runAttemptCount < 3) Result.retry() else Result.failure()
}
}
}
// Agendamento de tarefa 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)
}O código mostra duas abordagens para trabalho em segundo plano no Android. SyncService — um Foreground Service com notificação para trabalho imediato e prolongado em segundo plano. DataSyncWorker — WorkManager para tarefas adiadas com condições (Wi-Fi, carregamento). O WorkManager garante a execução mesmo após reinicialização do dispositivo e suporta backoff exponencial para tentativas. Foreground Service requer uma notificação persistente na barra de status.
Ambas as plataformas móveis estão constantemente endurecendo as regras de trabalho em segundo plano. No iOS, cada nova geração do SO reduz o tempo de execução em segundo plano e adiciona novas restrições. No Android, o Google introduz modos de economia de energia cada vez mais rigorosos (Doze, App Standby). Os desenvolvedores devem manter-se atualizados com as limitações atuais para evitar que o aplicativo seja encerrado prematuramente pelo sistema.
No iOS, a partir do iOS 13, o sistema desativa tarefas em segundo plano para aplicativos que abusam do tempo em segundo plano. Cada aplicativo recebe certos limites com base no comportamento do usuário. BGTaskScheduler agenda a execução em momentos ideais — por exemplo, quando o dispositivo está conectado ao Wi-Fi e carregando. Aplicativos que usam corretamente o BGTaskScheduler obtêm mais tempo em segundo plano.
No Android, a partir do Android 9 (API 28), o trabalho em segundo plano é restrito pelo modo Doze, que é ativado quando o dispositivo está inativo. Aplicativos em Doze não podem realizar tarefas em segundo plano, a rede é desconectada, JobScheduler e WorkManager adiam tarefas até sair do Doze. Foreground Service é a única maneira de contornar o Doze, mas o abuso leva ao bloqueio do aplicativo pelo usuário e revogação de permissões.
| Restrição | iOS | Android |
|---|---|---|
| Timeout de tarefa em segundo plano | ~30 segundos (beginBackgroundTask) | Vários minutos (JobScheduler) |
| Segundo plano ilimitado | Áudio, VoIP, navegação, Bluetooth | Foreground Service + notificação |
| Economia de energia | Low Power Mode — desativa tarefas em segundo plano | Doze, App Standby, Otimização de Bateria |
| Agendamento | BGTaskScheduler (iOS 13+) | WorkManager (Android Jetpack) |
| Após reinicialização | Apenas notificação push | WorkManager mantém as tarefas |
| Tempo máximo de execução | ~30 minutos (áudio) | Ilimitado (Foreground Service) |
Primeira regra — minimize o consumo de recursos em segundo plano. A maioria das tarefas em segundo plano pode ser adiada para quando o dispositivo estiver carregando e conectado ao Wi-Fi. Use BGTaskScheduler (iOS) e WorkManager (Android) para agendar tarefas com condições. Não execute cálculos pesados em segundo plano — isso drena a bateria e leva à limitação da CPU.
Segunda regra — sempre especifique um expirationHandler para beginBackgroundTask. Se o aplicativo não concluir a tarefa no tempo alocado, o sistema o forçará a passar para Suspended ou o encerrará. O expirationHandler é a última chance para salvar dados e finalizar o trabalho corretamente. No Android, use setForegroundAsync no WorkManager para converter uma tarefa normal em primeiro plano se mais tempo for necessário.
Terceira regra — verifique as restrições de trabalho em segundo plano antes de iniciar. No iOS, use UIApplication.shared.backgroundTimeRemaining para verificar o tempo restante. No Android, verifique ActivityManager.isBackgroundRestricted() — se for true, o aplicativo não pode executar tarefas em segundo plano, e você deve sugerir que o usuário remova as restrições nas configurações. Isso é especialmente importante para aplicativos com funções críticas em segundo plano — alarmes, calendários, sincronização.
Quarta regra — teste tarefas em segundo plano em um dispositivo real. Simuladores e emuladores não reproduzem as restrições reais de trabalho em segundo plano. No iOS, use Debug → Simulate Background Fetch no Xcode. No Android, use adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED para testar o WorkManager após reinicialização. Testes reais em um dispositivo com bateria baixa revelam a maioria dos problemas de trabalho em segundo plano.
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("Tempo restante em segundo plano: \(remaining) seg")
let task = UIApplication.shared.beginBackgroundTask { [weak self] in
print("Tempo esgotado para a tarefa: \(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)
}
}O código mostra um gerenciador de tarefas em segundo plano que rastreia o tempo restante e gerencia identificadores. backgroundTimeRemaining retorna o número de segundos antes do encerramento forçado — se o valor for infinito, o aplicativo está sendo executado sem restrições (áudio, navegação). O gerenciador permite iniciar várias tarefas em segundo plano com diferentes nomes e concluir cada uma corretamente. Esta abordagem evita vazamentos de tarefas em segundo plano e garante que o sistema não encerre o aplicativo devido a tarefas não fechadas.
Perguntas Frequentes
Sim, para um número limitado de categorias: áudio (AVAudioSession categoria .playback), VoIP (PushKit), navegação (CLLocationManager com allowsBackgroundLocationUpdates), Bluetooth (modo central em segundo plano), atualização em segundo plano (BGTaskScheduler). Para todas as outras — no máximo 30 segundos. No iOS 16+, a Apple endureceu os requisitos mesmo para categorias permitidas.
beginBackgroundTask é uma API síncrona para estender a vida do aplicativo em ~30 segundos após ir para segundo plano. É chamado em applicationDidEnterBackground. BGTaskScheduler é uma API assíncrona para agendar tarefas no futuro através de gatilhos do sistema (tempo, localização, atualização de conteúdo). BGTaskScheduler é a abordagem moderna, recomendada pela Apple para iOS 13+.
A partir do Android 8 (API 26), um Background Service é encerrado alguns minutos após o aplicativo ir para segundo plano. Solução: use um Foreground Service com notificação para operações longas ou WorkManager para tarefas adiadas. Verifique a Otimização de Bateria para seu aplicativo nas configurações — se estiver otimizado, o sistema pode adiar ou cancelar tarefas em segundo plano.
Pressione Cmd+Shift+H para ir à Tela Inicial. No Xcode, use Debug → Simulate Background Fetch. Para verificar beginBackgroundTask, abra o console (Shift+Cmd+C) e chame e UIApplication.shared.backgroundTimeRemaining. No Xcode 15+, um cenário de Background Execution está disponível na aba Diagnostics do simulador.
Process Death é o encerramento de um processo Android pelo sistema quando há poucos recursos ou quando está ocioso em segundo plano. Ao contrário do iOS, o Android não tem Suspended — o processo ou está vivo (pode estar em segundo plano) ou morto (Not Running). Process Death é um comportamento normal do SO, e o aplicativo deve restaurar corretamente o estado após isso via SavedStateHandle, onSaveInstanceState ou DataStore.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também