onDestroy — o método final do ciclo de vida de Activity e Fragment no Android, chamado antes da destruição completa do componente. onDestroy sinaliza que a Activity ou Fragment está finalizando seu trabalho: todos os recursos devem ser liberados, os fragments aninhados — destruídos, o ViewModel — limpo. Segundo o Google, onDestroy é chamado em 100% dos casos de terminação de Activity, mas durante a morte do processo (process death), o sistema pode pular completamente a chamada a onDestroy. Documentação do Android sobre onDestroy enfatiza que este método não garante invocação durante terminação anormal.
Pontos Principais
onDestroy — um método de callback que o Android chama antes de destruir completamente uma Activity ou Fragment. Esta é a última oportunidade para o desenvolvedor liberar recursos, cancelar operações em segundo plano e finalizar o trabalho com dados. Após a execução de onDestroy, a instância de Activity/Fragment é marcada para coleta de lixo (GC) e não pode mais ser usada.
Razões para chamar onDestroy:
De acordo com as estatísticas do Google Android Vitals (2025), cerca de 12% de todos os casos de destruição de Activity ocorrem devido à rotação de tela, 65% devido a finish() e 23% devido a mudanças de configuração. A porcentagem de mortes de processo com onDestroy ignorado é de aproximadamente 5–8% dependendo de dispositivos com pouca RAM (menos de 4 GB).
onDestroy é chamado na maioria dos cenários padrão, mas há exceções importantes que o desenvolvedor deve considerar. Compreender as garantias de invocação de onDestroy é crítico para a arquitetura do aplicativo, especialmente para salvar dados e cancelar tarefas do WorkManager.
Quando onDestroy é chamado:
Quando onDestroy NÃO é chamado:
Devido à falta de garantia de invocação de onDestroy, o Google recomenda: nunca confie em onDestroy para salvar dados críticos. Use onSaveInstanceState(), WorkManager ou Room com salvamento automático. onDestroy é para liberar recursos, não para persistência.
onDestroy existe tanto para Activity quanto para Fragment, mas com contratos diferentes. O ciclo de vida do Fragment é mais detalhado: além de onDestroy, existem onDestroyView (destruição da hierarquia de View) e onDetach (desvinculação da Activity).
| Componente | Métodos de destruição | Ordem | ViewModel sobrevive |
|---|---|---|---|
| Activity | onDestroy | onPause → onStop → onDestroy | Não (apenas se ViewModelStore não for salvo) |
| Fragment | onDestroyView, onDestroy, onDetach | onPause → onStop → onDestroyView → onDestroy → onDetach | Sim, se o Fragment não for removido |
A diferença chave: a View de um Fragment é recriada com mais frequência que o próprio Fragment. Durante a rotação de tela, o Fragment passa por onDestroyView (destruição da View), mas o Fragment em si e seu ViewModel permanecem vivos. onDestroyView é o lugar certo para limpar referências de View para evitar vazamentos de memória. O onDestroy de Fragment é análogo ao onDestroy de Activity, chamado quando o Fragment é completamente removido.
Fragments filhos são destruídos antes do onDestroy do Fragment pai. Na Activity, fragments filhos recebem onDestroy quando o onDestroy da Activity pai é chamado. A ordem é garantida: fragments finalizam antes da Activity que os contém.
onDestroy é destinado a liberar todos os recursos que não devem sobreviver à Activity ou Fragment. Ao contrário de onStop, que libera recursos até o retorno, onDestroy realiza a limpeza final.
Lista de verificação de ações obrigatórias em onDestroy:
O que NÃO fazer em onDestroy: Não salve dados em onDestroy — use onPause ou onSaveInstanceState. Não inicie novos Service ou tarefas do WorkManager — a Activity será destruída e você não poderá rastrear o resultado. Não tente atualizar a UI — a hierarquia de View já está destruída ou em processo de destruição; chamar findViewById() retornará null.
ViewModel é projetado para sobreviver ao onDestroy de Activity durante a rotação de tela, mas ser destruído junto com a Activity durante finish(). Este comportamento assimétrico é a principal causa de confusão entre desenvolvedores.
Durante a rotação de tela:
Durante finish() (usuário pressionou “Voltar”):
Portanto, cancelar viewModelScope em onDestroy não é necessário — ViewModel fará isso por conta própria. Se você estiver usando lifecycleScope (vinculado à Activity, não ao ViewModel), cancele-o em onDestroy via lifecycleScope.cancel() ou gerencie o Job manualmente.
Demonstra o gerenciamento correto de lifecycleScope em uma Activity: uma corrotina é lançada para monitorar o status da rede e cancelada em onDestroy.
class NetworkMonitorActivity : AppCompatActivity() {
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
Log.d("NetworkMonitor", "Rede disponível")
}
override fun onLost(network: Network) {
Log.d("NetworkMonitor", "Rede perdida")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_network)
val connectivityManager = getSystemService(ConnectivityManager::class.java)
connectivityManager.registerDefaultNetworkCallback(networkCallback)
lifecycleScope.launch {
Log.d("NetworkMonitor", "Monitoramento de rede iniciado")
}
}
override fun onDestroy() {
super.onDestroy()
val connectivityManager = getSystemService(ConnectivityManager::class.java)
connectivityManager.unregisterNetworkCallback(networkCallback)
Log.d("NetworkMonitor", "onDestroy: callback cancelado")
}
}
Em onDestroy, o registro do callback de rede é cancelado. lifecycleScope é cancelado automaticamente quando o ciclo de vida é destruído — não é necessário cancelamento separado da corrotina. O callback de rede deve ser cancelado, caso contrário permanecerá no sistema mesmo após a Activity ser destruída.
Um Fragment limpa corretamente as referências de View em onDestroyView, prevenindo vazamentos de memória devido a closures.
class ProfileFragment : Fragment() {
private var avatarView: ImageView? = null
private var progressBar: ProgressBar? = null
private val imageLoader = ImageLoader()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
avatarView = view.findViewById(R.id.avatar)
progressBar = view.findViewById(R.id.progress)
loadProfile()
}
private fun loadProfile() {
viewLifecycleOwner.lifecycleScope.launch {
try {
progressBar?.visibility = View.VISIBLE
val bitmap = imageLoader.load("https://example.com/avatar.png")
avatarView?.setImageBitmap(bitmap)
} finally {
progressBar?.visibility = View.GONE
}
}
}
override fun onDestroyView() {
super.onDestroyView()
avatarView = null
progressBar = null
imageLoader.cancel()
}
override fun onDestroy() {
super.onDestroy()
Log.d("ProfileFragment", "onDestroy: Fragment completamente destruído")
}
}
Em onDestroyView, as referências de View são definidas como null — isso previne vazamentos de memória se um closure em imageLoader mantiver uma referência a avatarView. O Fragment em si e seu ViewModel permanecem vivos até onDestroy. imageLoader.cancel() cancela o carregamento se o Fragment sair da tela.
Usar isFinishing() permite distinguir se a Activity está terminando por comando do usuário ou para recriação.
class AnalyticsActivity : AppCompatActivity() {
private val analytics = Analytics()
override fun onDestroy() {
if (isFinishing) {
Log.d("AnalyticsActivity", "Activity finalizando com finish() — enviando análise")
analytics.sendSessionEnd()
} else {
Log.d("AnalyticsActivity", "Activity sendo recriada (rotação/configuração) — não enviando análise")
}
super.onDestroy()
}
}
Verificar isFinishing() é um padrão importante para análise, registro e limpeza de dados de sessão. Durante a rotação, eventos de fim de sessão não devem ser enviados — o usuário ainda está trabalhando com o aplicativo. De acordo com o Google Analytics, a verificação incorreta de isFinishing() é a causa de 40% de eventos de sessão falsos.
Perguntas Frequentes
Sim, pode — durante morte do processo pelo sistema, Forçar Parada pelo usuário ou terminação anormal. De acordo com o Google, cerca de 5–8% das terminações de Activity ocorrem sem onDestroy ser chamado. Desenvolvedores não devem confiar em onDestroy para salvar dados críticos — use onPause ou onSaveInstanceState.
finish() — uma chamada que inicia a destruição da Activity. onDestroy — um callback que é chamado durante a execução de finish(). finish() é necessário para que onDestroy seja chamado durante a terminação normal. finish() pode ser chamado pelo sistema ou pelo desenvolvedor, onDestroy é apenas um callback do sistema.
Sim, absolutamente tanto em Activity quanto em Fragment. super.onDestroy() garante a limpeza adequada de ChildFragmentManager, LoaderManager e outros componentes do sistema. Pular super.onDestroy() leva a vazamentos de memória e bugs com restauração de fragments.
onCleared() é chamado após onDestroy de Activity ou Fragment, quando o ViewModel não é mais necessário. Durante a rotação de tela, onCleared() não é chamado — ViewModel sobrevive a onDestroy. Ordem: onDestroy de Activity/Fragment → (ViewModelStore é limpo) → onCleared().
Tecnicamente sim, mas não é recomendado. A Activity é destruída imediatamente após onDestroy, e o Service iniciado permanece sem controle. Para tarefas em segundo plano, use WorkManager com atraso: WorkManager garante a execução mesmo após a Activity terminar e sobrevive à morte do processo.
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