Inactive — o estado de transição entre Active e Background

Autor: IT Sectr Publicado: 2026-03-03 Tempo de leitura: 10 min

Inactive — um estado transitório no ciclo de vida da aplicação entre Active e Background, no qual o app está visível na tela mas não recebe eventos de toque. Explicamos como o Inactive ocorre no iOS e Android, quais métodos do delegado o tratam e como processar corretamente as interrupções — chamadas, notificações e gestos do sistema.

Principais pontos

  • Inactive — o app está visível na tela mas não recebe eventos de toque devido a uma interrupção do sistema
  • applicationWillResignActive — o método principal que sinaliza a transição para Inactive no iOS
  • Natureza temporária — Inactive dura de frações de segundo a vários segundos, depois transita para Active ou Background
  • Causas — chamada recebida, Control Center, Notification Center, alerta do sistema, Apple Pay, Siri
  • SwiftUI — scenePhase .inactive é equivalente ao Inactive no UIKit

Inactive — a essência do estado de transição

Inactive é um estado intermediário no ciclo de vida do aplicativo móvel que ocorre durante a transição entre Active e Background. Neste estado, o app ainda está em primeiro plano e visível para o usuário, mas não recebe eventos de toque, pressionamentos de tecla ou outros eventos de UI. O sistema bloqueia a entrega de eventos ao app, mas a UI permanece na tela e não é minimizada.

A natureza do Inactive é temporária. Este estado dura exatamente o tempo da interrupção do sistema: de 0.1 segundos ao fechar rapidamente o Control Center a vários segundos durante uma chamada recebida com tela de chamada. Após o término da interrupção, o app retorna ao Active ou transita para Background se o usuário mudou para outro app. Inactive é o único estado que pode transitar em ambas as direções: de volta ao Active ou adiante para Background.

No iOS, o Inactive é gerenciado automaticamente pelo sistema. O desenvolvedor não pode estender ou encurtar o tempo no Inactive — é totalmente controlado pelo UIApplication. A única coisa que o desenvolvedor pode fazer é tratar corretamente a transição para Inactive através do applicationWillResignActive e o retorno através do applicationDidBecomeActive. No Android, o equivalente é onPause, embora a semântica difira: onPause é chamado mesmo quando uma Activity está parcialmente coberta por outro componente.

Comparação do Inactive no iOS e Android

No iOS, Inactive é um estado separado do ciclo de vida da aplicação (um de cinco: Not Running, Active, Inactive, Background, Suspended). No Android não há equivalente direto — onPause sinaliza que a Activity está perdendo o foco de entrada mas pode permanecer visível (por exemplo, quando um diálogo abre). A diferença chave: Inactive no iOS é um estado de todo o app, enquanto onPause no Android é um estado por Activity. No multi-janela do Android, uma Activity pode estar em onPause (sem foco) enquanto outra está em onResume (com foco).

CaracterísticaiOS InactiveAndroid onPause
UI visívelSimSim (parcial ou totalmente)
Eventos de toqueNão recebeNão recebe
DuraçãoAté o fim da interrupçãoAté o retorno do foco ou ida para segundo plano
Próximo estadoActive ou BackgroundonResume ou onStop
NívelApp (UIApplication)Activity
Multi-janelaUma cena ativaMúltiplas Activity em onPause

Quando o Inactive ocorre

Inactive no iOS ocorre em vários cenários estritamente definidos. O usuário abre o Control Center (deslizar para baixo do canto superior direito no iPhone X+ ou deslizar para cima em modelos antigos). O usuário abre o Notification Center (deslizar para baixo do canto superior esquerdo). Uma chamada recebida chega — o sistema mostra a tela de chamada sobre o app. Uma permissão do sistema é solicitada — geolocalização, microfone, câmera, contatos. No iPad, o Slide Over ou Split View é iniciado — a cena ativa se torna Inactive.

No Android, onPause (o equivalente de Inactive) ocorre numa gama ainda mais ampla de situações. Abertura de um diálogo (AlertDialog, DialogFragment). Sobreposição parcial de uma Activity por outra Activity (por exemplo, uma Activity transparente para autenticação). Rotação de tela (a Activity é recriada, sequência: onPause → onStop → onDestroy → onCreate → onStart → onResume). Modo multi-janela — a janela inativa recebe onPause. Cada um desses eventos requer a suspensão de operações intensivas em recursos para preservar a bateria e o desempenho.

swift
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) {
        // O aplicativo transita para Inactive — interrupção do sistema
        print("Interrupção: Control Center, chamada ou alerta do sistema")

        // Pausar operações sensíveis ao tempo
        pauseVideoPlayback()
        stopContinuousDataCollection()
        hideSensitiveInformation()

        // Notificar componentes
        NotificationCenter.default.post(name: .systemInterruptionBegan, object: nil)
    }

    // Retorno de Inactive para Active
    func applicationDidBecomeActive(_ application: UIApplication) {
        resumeVideoPlayback()
        restartDataCollection()
        NotificationCenter.default.post(name: .systemInterruptionEnded, object: nil)
    }

    private func pauseVideoPlayback() {
        // Pausar o vídeo para que o áudio não se sobreponha
    }

    private func hideSensitiveInformation() {
        // Ocultar dados sensíveis na captura de tela
        // Control Center/App Switcher tiram uma captura da UI
    }
}

O código mostra o tratamento do Inactive no UIKit. applicationWillResignActive pausa o vídeo, interrompe a coleta de dados e oculta informações sensíveis. Isto é importante porque ao abrir o Control Center ou App Switcher, o sistema tira uma captura da UI atual — o usuário poderia ver dados confidenciais na pré-visualização. O NotificationCenter permite que os componentes do app se inscrevam em eventos de interrupção.

Inactive no iOS: Swift e UIKit

No iOS, Inactive é tratado por um par de métodos: applicationWillResignActive (transição para Inactive) e applicationDidBecomeActive (retorno do Inactive). Estes métodos fazem parte do UIApplicationDelegate e são chamados para cada transição através do Inactive. Desde o iOS 13 e UISceneDelegate, foram adicionados sceneWillResignActive e sceneDidBecomeActive para cenários multi-janela.

SceneDelegate e Inactive multi-janela

No iPad com iOS 13+, um app pode ter múltiplas cenas (janelas). Cada cena tem seu próprio ciclo de vida. Uma cena pode se tornar Inactive (o usuário mudou para outra cena) enquanto outra permanece Active. Esta é uma diferença importante do iPhone, onde Inactive é um estado global para todo o app. Ao desenvolver para iPad, é necessário tratar o Inactive para cada cena separadamente.

swift
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    // A cena se torna inativa
    func sceneWillResignActive(_ scene: UIScene) {
        // No iPad esta cena perde o foco, mas outras podem estar ativas
        print("A cena perde atividade")

        // Pausar as tarefas desta cena
        pauseSceneSpecificOperations()
    }

    // A cena se torna ativa
    func sceneDidBecomeActive(_ scene: UIScene) {
        print("A cena se tornou ativa")
        resumeSceneSpecificOperations()
    }

    private func pauseSceneSpecificOperations() {
        // Pausar operações específicas desta cena
    }

    private func resumeSceneSpecificOperations() {
        // Retomar operações quando o foco retorna
    }
}

// AppDelegate permanece o ponto de entrada, delega para as cenas
@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        configurationForConnecting connectingSceneSession: UISceneSession,
        options: UIScene.ConnectionOptions
    ) -> UISceneConfiguration {
        return UISceneConfiguration(
            name: "Default Configuration",
            sessionRole: connectingSceneSession.role
        )
    }
}

O código mostra um SceneDelegate para tratar o Inactive no nível da cena. sceneWillResignActive é chamado quando uma janela específica perde o foco — isto pode ocorrer ao alternar entre janelas no iPad. O AppDelegate configura o UISceneConfiguration para suportar multi-janela. Cada cena tem um estado independente e o desenvolvedor deve tratá-las separadamente.

Inactive no Android: onPause e visibilidade

No Android, o equivalente direto do Inactive do iOS é o método onPause() do ciclo de vida da Activity. Ele é chamado quando a Activity perde o foco de entrada mas pode permanecer visível. Cenários típicos: abertura de um diálogo, lançamento de outra Activity no mesmo app, chamada recebida, pressionar o botão Home ou Recents. No onPause, o desenvolvedor deve suspender operações intensivas em recursos — animações, reprodução de vídeo, trabalho com câmera.

Uma diferença importante do Android é que onPause sempre precede onStop, mas não o contrário. Uma Activity pode receber onPause sem onStop (por exemplo, ao abrir uma Activity transparente). Além disso, onPause pode ser chamado múltiplas vezes durante a vida de uma Activity — em cada troca de foco. Não coloque lógica única no onPause — use onStop para operações finais e onPause apenas para suspender ações interativas.

kotlin
class VideoPlayerActivity : AppCompatActivity() {

    private var exoPlayer: ExoPlayer? = null
    private var currentPosition: Long = 0L

    override fun onPause() {
        super.onPause()
        // O aplicativo perde o foco — pausamos o vídeo
        exoPlayer?.let { player ->
            if (player.isPlaying) {
                currentPosition = player.currentPosition
                player.pause()
            }
        }
        // Ocultamos dados sensíveis (GDPR/telas bancárias)
        if (window.decorView.systemUiVisibility and
            View.SYSTEM_UI_FLAG_SECURE == 0
        ) {
            hideSensitiveOverlay()
        }
    }

    override fun onResume() {
        super.onResume()
        // O foco retorna — retomamos a reprodução
        exoPlayer?.seekTo(currentPosition)
        exoPlayer?.play()
        showSensitiveOverlay()
    }

    private fun hideSensitiveOverlay() {
        // Sobrepor uma tela preta sobre dados financeiros
    }
}

O código mostra o tratamento correto do onPause para um player de vídeo. ExoPlayer é pausado quando o foco é perdido, e a posição de reprodução é salva. Ao retornar ao onResume, o player retoma a reprodução da posição salva. Adicionalmente, um padrão para ocultar dados sensíveis é mostrado — importante para aplicações financeiras e médicas que exigem proteção contra capturas de tela ao alternar.

Melhores práticas para lidar com Inactive

Primeira regra — oculte dados confidenciais ao transitar para Inactive. Quando o usuário abre o Control Center ou App Switcher, o iOS tira uma captura da tela atual. No Android, similarmente, o sistema mostra uma prévia da última Activity no Recents. Use UIApplication.shouldSnapshotSecureApp (iOS 16+) ou FLAG_SECURE (Android) para proteger telas confidenciais.

Segunda regra — pause animações e mídia. Inactive não é um bom momento para reproduzir vídeo ou animações, já que o usuário não pode vê-los. Além disso, a reprodução em segundo plano pode sobrepor o áudio com sons do sistema (toque, notificação). Pare AVPlayer, ExoPlayer e UIView.animate ao ir para Inactive e retome ao voltar para Active.

Terceira regra — bloqueie a entrada de dados. Se o app contém formulários de entrada ou rascunhos, bloqueie o teclado e os campos de entrada ao ir para Inactive. Isto evita entrada acidental ao retornar e protege contra interceptação de dados através de sobreposições do sistema. No iOS, renuncie ao primeiro respondedor (view.endEditing(true)), no Android — limpe o foco (currentFocus?.clearFocus()).

Quarta regra — não realize operações longas no applicationWillResignActive ou onPause. Estes métodos devem completar em frações de segundo. Se precisar salvar uma grande quantidade de dados, comece a salvar numa thread em segundo plano e complete no applicationDidEnterBackground ou onStop. O iOS dá 5 segundos para executar o applicationWillResignActive, após o qual o sistema pode forçar o encerramento do app.

swift
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
    }
}

// Uso no AppDelegate
func applicationWillResignActive(_ application: UIApplication) {
    SecureOverlayManager().showBlurOverlay()
}

func applicationDidBecomeActive(_ application: UIApplication) {
    SecureOverlayManager().removeBlurOverlay()
}

O código mostra a implementação de uma sobreposição segura para proteção de dados durante a transição para Inactive. Uma UIVisualEffectView com efeito blur é sobreposta sobre toda a UI ao ir para Inactive e removida ao voltar para Active. Isto garante que dados confidenciais não serão visíveis nas capturas do App Switcher e Control Center. Similarmente, você pode usar UIImageView com um logotipo para uma sobreposição personalizada.

Perguntas frequentes

Inactive sempre precede Background?

Sim. Inactive é um estado intermediário obrigatório antes de transitar para Background no iOS. Um app não pode ir de Active diretamente para Background — primeiro ele se torna Inactive, depois Background. No Android, similarmente, onPause é sempre chamado antes de onStop. Isto dá ao desenvolvedor a oportunidade de preparar dados para salvar antes de ir completamente para o segundo plano.

Um app pode se tornar Inactive sem uma interrupção?

Sim. No iPad, ao iniciar Slide Over ou Split View, a cena ativa se torna Inactive, mesmo que nenhuma interrupção do sistema ocorra — o usuário está simplesmente interagindo com outra cena. Esta é uma característica do iPadOS multi-janela. No iPhone, Inactive é sempre acionado por uma interrupção do sistema — chamada, notificação, Control Center ou Notification Center.

Quanto tempo um app pode permanecer em Inactive?

Geralmente de 0.1 a 2 segundos. Durante uma chamada recebida com tela de chamada — até 30 segundos (até o usuário atender ou recusar a chamada). O iOS não limita forçosamente o tempo em Inactive, mas o sistema pode encerrar o app se ele não responder a eventos (watchdog). No Android, onPause não tem limite de tempo, mas recomenda-se completar o trabalho em 200 ms.

O que é scenePhase no SwiftUI durante Inactive?

ScenePhase.inactive — o valor do enum ScenePhase definido quando a cena está em primeiro plano mas não recebe eventos. No SwiftUI, você pode observá-lo através de @Environment(\.scenePhase) e reagir via onChange. Ao transitar de .active para .inactive, pause temporizadores e animações. Ao retornar para .active, retome-os. Ao ir para .background, salve o estado.

É necessário ocultar a UI durante Inactive para todos os apps?

Não, apenas para apps que lidam com dados confidenciais: bancários, médicos, corporativos e de mensagens com chats privados. Para jogos e apps de entretenimento, ocultar a UI não é necessário. No entanto, pausar o jogo e o som durante Inactive é uma boa prática para evitar sobreposição de áudio com notificações do sistema. A Apple recomenda ocultar dados sensíveis mas não exige.

Resumo

  • Inactive — um estado de transição entre Active e Background, o app está visível mas não interativo
  • Causas — Control Center, Notification Center, chamada recebida, permissões do sistema, Siri, Apple Pay
  • Tratamento no iOS — applicationWillResignActive para pausar animações, mídia e ocultar dados sensíveis
  • SwiftUI — scenePhase .inactive via Environment, onChange para efeitos colaterais
  • Android — onPause como equivalente, com suporte a multi-janela e sobreposição parcial de Activity
  • Segurança — sobreposição com blur ou FLAG_SECURE para proteger contra capturas do App Switcher e Control Center
  • Natureza temporária — Inactive dura até a interrupção terminar, então retorna a Active ou vai para Background

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.

Discutir o projeto

Leia também