Warm Start: essência, inicialização a quente e otimização no Android

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

Warm Start é um cenário de inicialização de aplicativo Android onde o processo do aplicativo já existe na memória (por exemplo, após ser minimizado), mas a Activity foi destruída pelo sistema para economizar recursos. Application.onCreate já foi executado, as classes estão carregadas, mas a UI é criada novamente. De acordo com Google, 2024, o Warm Start leva de 200 a 800 ms e representa cerca de 40% de todas as inicializações em dispositivos com 4 GB de RAM.

Principais pontos

  • Warm Start — inicialização de um aplicativo com processo existente, mas sem Activity na memória
  • Diferença do Cold Start: Application.onCreate não é executado, classes já estão carregadas
  • Tempo Warm Start leva 200–800 ms contra 1–5 segundos para Cold Start
  • Cenários: retorno ao aplicativo após várias horas, remoção de Activity pelo OOM-killer
  • Otimização foca em preservar o estado da Activity e cache de dados

O que é Warm Start

Warm Start é um estado entre Cold Start e Hot Start: o processo do aplicativo existe na memória (às vezes no cache de segundo plano do Linux), mas a Activity não está ativa e será criada novamente. Quando o Android fica sem RAM, ele pode remover a Activity da pilha, deixando o processo vivo. Quando o usuário retorna ao aplicativo, ocorre um Warm Start: uma nova instância de Activity é criada, os métodos de ciclo de vida onCreate → onStart → onResume são executados, mas Application.onCreate e o carregamento de classes são ignorados.

Causas do Warm Start

O Android decide remover a Activity com base na prioridade do processo (classificação de importância). Uma Activity em segundo plano (nível PROCESS_STATE_IMPORTANT_FOREGROUND ou PROCESS_STATE_TOP_SLEEPING) pode ser destruída 5–30 minutos após minimizar o aplicativo, dependendo da RAM disponível. Em dispositivos com 3 GB de RAM, a Activity pode ser removida em 10 minutos; em dispositivos com 8 GB de RAM, após várias horas. Importante: durante o Warm Start, onSaveInstanceState é chamado antes da Activity ser destruída, e o desenvolvedor pode salvar o estado da UI.

Percepção do usuário

O usuário não vê diferença entre Warm e Cold Start — ele simplesmente toca no ícone do aplicativo e espera. No entanto, durante o Warm Start, uma tela branca pode aparecer se o aplicativo não tiver definido um tema personalizado para a janela de inicialização. Google recomenda definir um tema personalizado no manifesto (Theme.AppCompat.Light ou Theme.Material3.DayNight) para a Activity de inicialização, para evitar cintilação de tela branca/preta durante o Warm Start. No Android 12+, a API SplashScreen também oculta esse efeito.

Warm Start vs Cold Start vs Hot Start

Entender a diferença entre os três tipos de inicialização é essencial para escolher a estratégia correta de perfilamento e otimização. Cada tipo tem sua própria duração, seus gargalos e suas ferramentas de medição.

CritérioCold StartWarm StartHot Start
ProcessoCriado do zeroExiste na memóriaExiste na memória
Application.onCreateExecutadoNão executadoNão executado
ActivityCriada do zeroCriada do zeroRestaurada da pilha
Tempo1–5 segundos200–800 ms< 200 ms
Activity.onCreateCompletoCompleto (com restauração)Ignorado

Na prática, o Warm Start representa de 30% a 60% de todas as inicializações de aplicativos, dependendo dos hábitos do usuário e da RAM do dispositivo. Usuários que mantêm muitos aplicativos abertos (multitarefa) encontram Warm Start com mais frequência. Para redes sociais e mensageiros, Warm Start é o cenário mais comum, pois o aplicativo está sempre em segundo plano. Para aplicativos bancários, ao contrário, o Cold Start predomina (limpeza forçada do processo por razões de segurança).

Fases da inicialização a quente

O Warm Start consiste em três fases, cada uma pode ser medida e otimizada. Ao contrário do Cold Start, não há fase de fork ou carregamento de classes, mas há uma fase de restauração de estado que pode ser cara.

Fase 1: Janela de inicialização (fundo da janela)

O sistema verifica se o aplicativo tem um tema para a janela de inicialização. Se o tema não estiver definido, uma tela branca (ou preta, dependendo do sistema) é exibida. Se o tema estiver definido, o fundo do tema é mostrado. Esta fase leva 10–30 ms, mas é visualmente perceptível se o tema não corresponder à UI real do aplicativo. Use Theme.Material3.DayNight com um windowBackground personalizado cuja cor corresponda ao fundo da primeira tela — isso cria um efeito de carregamento instantâneo.

Fase 2: Criação da Activity (restauração)

O sistema chama onCreate passando o Bundle savedInstanceState que foi salvo em onSaveInstanceState antes da Activity ser destruída. Se o aplicativo salvou o estado corretamente (texto dos campos, posição de rolagem, dados do ViewModel), a restauração ocorre rapidamente. Caso contrário, a Activity começa do zero e o usuário vê um carregador enquanto os dados são carregados. Ponto chave: os objetos ViewModel sobrevivem ao Warm Start apenas se o processo não foi destruído — durante o Warm Start, o ViewModel permanece na memória.

Fase 3: Primeiro quadro (TTFD)

Após onCreate, onStart → onResume são executados, e o sistema aciona o primeiro desenho. TTFD (Time To First Draw) para Warm Start deve ser inferior a 300 ms em um dispositivo de gama média. Se a primeira tela contiver um RecyclerView complexo com Views pesadas ou carregar imagens da rede, o TTFD pode exceder o limite. Use Placeholder e Shimmer para carregamento suave de conteúdo após o primeiro quadro.

Como medir Warm Start

Medir Warm Start é mais complexo que Cold Start porque você precisa simular o estado onde o processo está vivo mas a Activity está destruída. O comando ADB padrão com a flag -S não funciona — ele mata o processo. Use abordagens diferentes para Warm Start.

ADB shell am start sem -S

Primeiro, inicie o aplicativo via adb shell monkey ou toque no ícone, depois minimize-o (adb shell input keyevent 3 keyevent HOME). Aguarde 5–10 segundos para o sistema remover a Activity, então execute adb shell am start -W (sem -S). O comando retornará um tempo de inicialização menor que o Cold Start. Para reprodutibilidade, use um script: iniciar → aguardar → home → aguardar → iniciar.

bash
# Simulação de Warm Start via ADB
$ adb shell am start -W \
    com.example.app/.MainActivity

# Saída (Warm Start):
# ThisTime: 412 ms
# TotalTime: 412 ms
# WaitTime: 423 ms

Macrobenchmark para Warm Start

A biblioteca androidx.benchmark.macro suporta medição de Warm Start. No teste, defina startupMode = StartupMode.WARM — a biblioteca iniciará o aplicativo, minimizará, aguardará (atraso configurável) e então medirá o reinício. Macrobenchmark executa 10–20 iterações e calcula percentis. Em CI/CD, você pode definir um limite: se P50 Warm Start exceder 600 ms, o teste falha. Isso permite rastrear regressões a cada commit.

Firebase Performance Monitoring

Firebase distingue automaticamente entre Cold e Warm Start com base no tempo desde o último fechamento do aplicativo. Se o aplicativo foi aberto nos últimos 30 minutos, Firebase classifica a inicialização como Warm. No console do Firebase, você verá gráficos separados para cada tipo de inicialização, permitindo avaliar a eficácia das otimizações. Por exemplo, após implementar a preservação de estado no ViewModel, você pode ver uma redução de 30% no tempo de Warm Start.

Como otimizar Warm Start

A otimização do Warm Start foca em duas áreas: acelerar Activity.onCreate e a restauração adequada do estado. Como Application.onCreate e o carregamento de classes já foram concluídos, o principal gargalo é o código de UI da primeira tela.

Restauração assíncrona de estado

Se o estado salvo (savedInstanceState) contém dados que precisam de desserialização (Bitmap, String, JSON), faça isso em uma thread de segundo plano. Em vez de ler diretamente do Bundle no onCreate, inicie uma corrotina e mostre uma tela shimmer. Na prática, a desserialização do Bundle em um dispositivo de gama média leva 20–100 ms — parece pouco, mas para Warm Start, isso é 10–50% do tempo total. Use o Saved State Module do Jetpack, que salva e restaura automaticamente o estado do ViewModel no Bundle ou banco de dados.

Otimização de setContentView

A inflação de layout XML é uma das etapas mais caras do Warm Start. Se a primeira tela usa um CoordinatorLayout complexo com AppBar, CollapsingToolbar, NestedScrollView mais três RecyclerViews, o tempo de inflação pode chegar a 300 ms. Soluções: use ConstraintLayout para hierarquia plana, aplique ViewStub para seções não visíveis na inicialização (bottom sheet, dialog), ative inflação assíncrona para fragments pesados via AsyncLayoutInflater. No Jetpack Compose, inflação não é necessária, mas a compilação da árvore Compose durante Warm Start pode levar tempo similar.

Cache de dados

Durante o Warm Start, os dados que o aplicativo carregou na sessão anterior podem já estar em cache: banco de dados Room, SharedPreferences, cache em memória no ViewModel. Se sua primeira tela exibe uma lista do servidor, verifique o cache na inicialização e atualize os dados em segundo plano. Use a estratégia cache-then-network: primeiro exiba dados em cache (instantaneamente), depois atualize do servidor (assincronamente). Isso reduz o tempo percebido de Warm Start para 100–200 ms.

kotlin
// ViewModel com cache para Warm Start
class FeedViewModel : ViewModel() {
    private val cache = MutableStateFlow<List<Item>>(emptyList())

    init {
        // Cache primeiro, depois rede
        viewModelScope.launch {
            cache.emit(db.getItems()) // Warm Start: dados já no BD
            cache.emit(api.fetchItems()) // Atualização em segundo plano
        }
    }
}

Preservação de estado durante Warm Start

A preservação adequada do estado é o fator chave que distingue um bom Warm Start de um ruim. O usuário espera retornar ao aplicativo e ver exatamente o que deixou — incluindo posição de rolagem, texto nos campos e abas selecionadas.

onSaveInstanceState

O sistema chama onSaveInstanceState quando a Activity está sendo destruída, mas ANTES do processo ser morto. Apenas tipos de dados simples (String, Int, Parcelable, Serializable) são salvos no Bundle. Para dados complexos, use SavedStateHandle no ViewModel — ele salva e restaura automaticamente os campos durante Warm Start. Ao contrário de onSaveInstanceState, SavedStateHandle funciona mesmo se o processo sobreviver ao Warm Start (ViewModel não é destruído). Exemplo: para texto em EditText, use SavedStateHandle.getLiveData(“text”) — o texto será salvo e restaurado automaticamente.

ViewModel e Warm Start

Se o processo não foi morto durante Warm Start, o ViewModel permanece na memória e onCleared não é chamado. Isso significa que todos os dados carregados na sessão anterior estão instantaneamente disponíveis. No entanto, se o processo foi morto (dispositivo em suspensão profunda por mais de 30 minutos), o ViewModel é destruído e criado novamente com SavedStateHandle. Para comportamento correto do ViewModel durante Warm Start, use SavedStateHandle com campos que precisam ser restaurados em qualquer cenário. Diferença: ViewModel com @HiltViewModel suporta SavedStateHandle automaticamente.

MecanismoProcesso vivoProcesso morto
ViewModelDados na memóriaDestruído, criado novamente
SavedStateHandleDados na memóriaRestaurado do Bundle
onSaveInstanceStateChamado ao remover ActivityNão chamado
Room DBCache disponívelCache disponível (disco)

Salvar posição de rolagem do RecyclerView

Um dos problemas mais comuns do Warm Start — perder a posição de rolagem. O usuário rolou até o 50º item, minimizou o aplicativo, voltou — e vê o início da lista. Solução: salve layoutManager.onSaveInstanceState (salva a posição e deslocamento do primeiro item visível) e restaure em onRestoreInstanceState. Você também pode salvar a última posição visível em SharedPreferences com uma chave de data/hora para restaurar rapidamente a posição durante Warm Start.

kotlin
// Salvar posição de rolagem do RecyclerView
override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putParcelable(
        "rv_state", binding.recyclerView
            .layoutManager?.onSaveInstanceState()
    )
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    savedInstanceState?.getParcelable<Parcelable>("rv_state")
        ?.let { binding.recyclerView.layoutManager?.onRestoreInstanceState(it) }
}

Exemplos de código para Warm Start

Dois exemplos práticos de otimização de Warm Start: uso de SavedStateHandle em ViewModel e restauração assíncrona de dados complexos após a inicialização.

ViewModel com SavedStateHandle

SavedStateHandle salva automaticamente os campos no Bundle e os restaura durante Warm Start. O campo de perfil do usuário (String, JSON) será restaurado sem solicitações desnecessárias ao servidor. Se o processo foi morto, SavedStateHandle carrega o último estado salvo do Bundle.

kotlin
class ProfileViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    val profile: StateFlow<Profile?>
        get() = savedStateHandle
            .getStateFlow("profile", null)

    fun loadProfile(id: String) {
        viewModelScope.launch {
            savedStateHandle["profile"] =
                api.getProfile(id)
        }
    }
}

// Warm Start: profile não é null, UI sem carregador
// Após carregar: profile atualiza no SavedStateHandle

AsyncLayoutInflater para telas pesadas

Se a primeira tela contém um layout complexo (mapa, gradiente, várias listas), use AsyncLayoutInflater para inflar elementos pesados em segundo plano. Enquanto o layout está sendo inflado, mostre um placeholder com efeito shimmer. Isso é especialmente importante para Warm Start, onde cada milissegundo conta. AsyncLayoutInflater é executado em uma thread de segundo plano e passa o View pronto para um callback na thread principal.

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Layout placeholder para renderização instantânea
        setContentView(R.layout.placeholder_shimmer)

        // Carregamento assíncrono de layout pesado
        AsyncLayoutInflater(this).inflate(
            R.layout.activity_main_complex,
            findViewById(R.id.container)
        ) { view, resId, parent ->
            parent?.removeAllViews()
            parent?.addView(view)
        }
    }
}

Perguntas frequentes

Warm Start pode se transformar em Cold Start?

Sim, se no momento do Warm Start o sistema decidir matar o processo do aplicativo (por exemplo, para liberar memória para outro aplicativo), a inicialização se torna Cold Start do zero. Isso acontece em dispositivos com 2–3 GB de RAM com vários aplicativos rodando simultaneamente. Na verdade, Warm Start só é garantido por 10–20 minutos após minimizar em dispositivos de gama média.

O ViewModel é preservado durante Warm Start?

Sim, se o processo não foi morto, o ViewModel permanece na memória e onCleared não é chamado. Esta é uma vantagem chave do Warm Start: todos os dados carregados por requisições de rede, o cache no ViewModel — tudo disponível instantaneamente. Se o processo foi morto, o ViewModel é criado novamente através de ViewModelProvider.Factory ou @HiltViewModel, e SavedStateHandle restaura os campos salvos.

Por que Warm Start pode ser mais lento que Cold Start?

Teoricamente, Warm Start é sempre mais rápido que Cold Start, mas na prática há cenários onde a diferença é mínima: se Application.onCreate foi leve (50 ms) e Activity.onCreate é pesado (800 ms), então Warm Start (800 ms) é quase igual a Cold Start (850 ms). Neste caso, você deve otimizar não Application, mas Activity.onCreate — ele se torna o gargalo para Warm Start.

Como a API SplashScreen afeta Warm Start?

A API SplashScreen no Android 12+ mostra um splash do sistema (ícone sobre fundo colorido) imediatamente na inicialização — tanto para Cold quanto para Warm Start. Para Warm Start, o splash é exibido por apenas 100–300 ms, após o que é substituído pela UI do aplicativo. SplashScreen não acelera a inicialização em si, mas mascara o tempo de criação da Activity, melhorando a percepção.

É necessário otimizar Warm Start se Cold Start já é rápido?

Sim, porque Warm Start ocorre 2–3 vezes mais que Cold Start. Se Cold Start leva 1.2 segundos e Warm Start leva 600 ms, então 40% das inicializações (Warm) ainda levam 0.6 segundos, o que é perceptível. Otimizar Warm Start para 200–300 ms dá ao usuário uma sensação de retorno instantâneo. Em dispositivos com 6+ GB de RAM, Warm Start pode representar até 80% de todas as inicializações, tornando sua otimização uma prioridade.

Resumo

  • Warm Start — inicialização de aplicativo com processo existente, sem Activity na memória, tempo 200–800 ms
  • Principal diferença do Cold Start: Application.onCreate não é executado, classes estão carregadas
  • Três fases do Warm Start: janela de inicialização → criação da Activity → primeiro quadro
  • Medido via ADB sem a flag -S ou Macrobenchmark com StartupMode.WARM
  • Otimização: SavedStateHandle, AsyncLayoutInflater, cache-then-network, ConstraintLayout
  • ViewModel é preservado durante Warm Start (processo vivo) — dados instantaneamente disponíveis
  • Warm Start representa 40–80% de todas as inicializações de aplicativos

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