onCreate é o primeiro e único método obrigatório do ciclo de vida de Activity e Fragment no Android. O sistema o chama uma vez ao criar um componente, passando o parâmetro Bundle com o estado previamente salvo. Dentro de onCreate, o desenvolvedor inicializa a interface do usuário, vincula os elementos View, configura os manipuladores de eventos e restaura os dados de savedInstanceState. Sem uma implementação correta de onCreate, nenhum aplicativo Android pode ser iniciado — é o ponto de entrada para cada tela. Para mais detalhes sobre o ciclo de vida geral da Activity, leia o artigo Activity Lifecycle.
Principais conclusões
onCreate é um método de callback que o Android chama ao criar uma nova instância de uma Activity ou Fragment. Este é o primeiro ponto de entrada no código da tela do usuário: nenhum código do usuário é executado antes de onCreate ser chamado. O sistema passa um parâmetro Bundle para o método, que contém dados salvos anteriormente (ao recriar) ou é null (na primeira inicialização).
O método onCreate é definido na classe android.app.Activity e na classe androidx.fragment.app.Fragment. Ambas as variantes realizam tarefas semelhantes: inicialização do componente, configuração da UI e restauração do estado. No entanto, a implementação específica difere — Activity usa setContentView para carregar o layout, enquanto Fragment retorna uma View através de onCreateView. O desenvolvedor deve sobrescrever pelo menos onCreate em Activity — sem isso, o Android não pode exibir a tela.
onCreate é chamado estritamente uma vez por ciclo de vida completo de uma instância de Activity. Mesmo na rotação da tela, uma nova instância de Activity recebe uma nova chamada de onCreate com o Bundle da instância anterior. Isso torna onCreate o local ideal para inicialização única: carregamento de dados, criação de adaptadores, configuração de componentes DI via Dagger ou Hilt.
Em Activity, o método onCreate realiza quatro tarefas principais: carregar o layout, inicializar os elementos View, restaurar o estado do Bundle e configurar os manipuladores de eventos primários. O código mínimo obrigatório em onCreate é chamar super.onCreate(savedInstanceState) e setContentView(R.layout.activity_main).
class MainActivity : AppCompatActivity() {
private var binding: ActivityMainBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ViewBinding — um substituto moderno para findViewById
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding?.root)
// Inicialização usando binding
binding?.apply {
welcomeText.text = getString(R.string.welcome)
startButton.setOnClickListener { startGame() }
}
// Restauração do estado
if (savedInstanceState != null) {
score = savedInstanceState.getInt("score", 0)
binding?.scoreText?.text = score.toString()
}
}
}
A prática moderna usa ViewBinding em vez de findViewById. ViewBinding gera a classe ActivityMainBinding em tempo de compilação, eliminando erros com IDs incorretos e reduzindo o código boilerplate. O Google recomenda ViewBinding como a forma padrão de acessar View em Activity e Fragment a partir do Android Studio 3.6.
A ordem das operações em onCreate deve ser rigorosa: primeiro super, depois setContentView, depois todo o resto. Chamar findViewById antes de setContentView retorna null — o layout ainda não foi carregado e os elementos View não existem na hierarquia. Este é um dos erros mais comuns de desenvolvedores Android iniciantes.
onCreate em Fragment difere de Activity: aqui setContentView não é chamado, apenas a inicialização de dados não relacionados à UI é realizada. Fragment separa a criação do componente e a criação da View em dois métodos distintos: onCreate (chamado uma vez) e onCreateView (chamado cada vez que a View é criada ou recriada).
class UserListFragment : Fragment() {
private lateinit var viewModel: UserViewModel
private var binding: FragmentUserListBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Inicialização de ViewModel — sobrevive à recriação da View
viewModel = ViewModelProvider(this)[UserViewModel::class.java]
// Argumentos do FragmentManager
arguments?.let {
viewModel.loadUser(it.getString("user_id") ?: "")
}
// Salvamento na rotação
retainInstance = true
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentUserListBinding.inflate(inflater, container, false)
return binding!!.root
}
}
A principal diferença entre onCreate de Activity e Fragment: onCreate em Fragment não deve conter código relacionado a View, porque a View pode ser destruída e recriada (por exemplo, ao alternar abas do ViewPager), enquanto onCreate é chamado apenas uma vez. Carregamento de dados, configuração de ViewModel e inicialização de adaptadores são tarefas de onCreate, enquanto a vinculação de View é tarefa de onViewCreated.
O parâmetro savedInstanceState em onCreate é um mecanismo para salvar e restaurar o estado temporário de uma Activity ou Fragment. Quando o sistema destrói uma Activity (rotação de tela, falta de memória), ele chama onSaveInstanceState(), onde o desenvolvedor coloca entradas chave-valor em um Bundle. Quando uma nova instância é criada, este Bundle é retornado em onCreate.
Bundle suporta os seguintes tipos de dados: String, Integer, Boolean, Long, Float, Double, seus arrays, bem como objetos Parcelable e Serializable. Para objetos complexos, usa-se Parcelable — um mecanismo de serialização mais eficiente específico do Android. O tamanho do Bundle é limitado a aproximadamente 500 KB — exceder o limite causa uma TransactionTooLargeException.
companion object {
private const val KEY_USER_NAME = "user_name"
private const val KEY_SCORE = "score"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_game)
if (savedInstanceState != null) {
userName = savedInstanceState.getString(KEY_USER_NAME) ?: ""
currentScore = savedInstanceState.getInt(KEY_SCORE)
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString(KEY_USER_NAME, userName)
outState.putInt(KEY_SCORE, currentScore)
}
É importante entender: onSaveInstanceState não é chamado quando o usuário fecha explicitamente a Activity via finish() ou botão Voltar. O sistema considera que o usuário está encerrando conscientemente o trabalho e não precisa salvar o estado. Portanto, você não pode confiar apenas em savedInstanceState para armazenamento de dados de longo prazo — use Room, DataStore ou SharedPreferences.
onCreate executa na thread principal (UI) e o sistema aguarda sua conclusão antes de exibir a Activity na tela. Se onCreate levar mais de 5 segundos, o sistema exibe uma caixa de diálogo ANR (Application Not Responding) e oferece ao usuário a opção de fechar o aplicativo. Operações longas, como carregar dados da rede ou ler de um banco de dados, devem ser movidas para uma thread em segundo plano.
De acordo com as recomendações do Google Android Performance (2025), onCreate deve ser concluído em menos de 1 segundo em dispositivos de médio porte. Para conseguir isso: use inicialização preguiçosa (lazy delegate em Kotlin), adie o carregamento de dados pesados para onResume ou via corrotinas, aplique ViewStub para componentes de UI raramente usados e faça perfil do tempo de inicialização através do Android Vitals.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Inicialização preguiçosa — objeto é criado apenas no primeiro acesso
val heavyData by lazy {
HeavyDataLoader.load()
}
// Carregamento de dados em thread de segundo plano via lifecycleScope
lifecycleScope.launch(Dispatchers.IO) {
val users = userDao.getAllUsers()
withContext(Dispatchers.Main) {
adapter.submitList(users)
}
}
}
Ferramentas de perfil: o Android Studio Profiler (aba CPU) mostra o tempo exato de execução de cada método. No Android Vitals (Google Play Console), você pode rastrear a métrica “Tempo de inicialização a frio” — se o onCreate da sua Activity exceder 500 ms, o console o marca como um problema de desempenho. Na IT Sectr, usamos testes Macrobenchmark para controle automático do tempo de inicialização de cada Activity no pipeline de CI.
ViewModel é a melhor maneira de inicializar dados em onCreate que devem sobreviver à rotação da tela. ViewModel é criado em onCreate via ViewModelProvider e é preservado automaticamente em mudanças de configuração. Quando uma Activity é recriada após rotação, o ViewModel permanece na memória e onCreate recebe o mesmo ViewModel sem perda de dados.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile)
// ViewModel é criado uma vez e sobrevive a mudanças de configuração
val viewModel: ProfileViewModel =
ViewModelProvider(this)[ProfileViewModel::class.java]
// Observação de LiveData — a UI é atualizada automaticamente quando os dados mudam
viewModel.user.observe(this) { user ->
binding?.userName?.text = user.name
binding?.userEmail?.text = user.email
}
// Carregamento de dados se ViewModel acabou de ser criado
if (savedInstanceState == null) {
viewModel.loadProfile(userId)
}
}
A combinação de ViewModel + LiveData/StateFlow resolve o problema de rotação de tela sem salvamento manual em Bundle. ViewModel armazena dados na memória, LiveData reatribui automaticamente a Activity na recriação, e StateFlow (do Kotlin Coroutines) adiciona reatividade com suporte a corrotinas. Esta é a arquitetura padrão recomendada pelo Google no Guide to App Architecture.
Mesmo desenvolvedores experientes cometem erros típicos em onCreate. Vamos ver os cinco problemas mais comuns e como evitá-los.
O erro mais comum é tentar encontrar uma View via findViewById antes de chamar setContentView. Todos os elementos View são criados no momento da inflação do layout, portanto qualquer chamada a findViewById antes de setContentView retorna null e causa uma NullPointerException ao tentar usar a View. Solução: ordem rigorosa — primeiro super, depois setContentView, depois findViewById ou ViewBinding.
Carregar dados da rede, ler de um banco de dados ou processar grandes arrays diretamente em onCreate bloqueia a renderização do primeiro quadro. O usuário vê uma tela preta até que onCreate termine, o que prejudica a percepção da velocidade do aplicativo. Solução: use lifecycleScope.launch para operações assíncronas, exiba um esqueleto (UI placeholder) até que o carregamento seja concluído.
Se você não restaurar o estado do Bundle na rotação da tela, o usuário perde toda a entrada não salva: texto em campos de formulário, posição de rolagem, itens selecionados. Solução: sempre verifique savedInstanceState != null em onCreate para restaurar dados, mesmo que a perda de estado pareça improvável.
Classes anônimas e lambdas em onCreate podem reter implicitamente uma referência a uma Activity após sua destruição. Por exemplo, um Handler criado em onCreate continua executando tarefas atrasadas mesmo após a Activity ser destruída. Solução: use LifecycleObserver, ViewModel e lifecycleScope, que cancelam automaticamente as tarefas na destruição.
Inicializar View em onCreate de Fragment é um erro lógico, pois a View pode ser recriada sem chamar onCreate. Se você definir um listener em onCreate mas vincular a View em onCreateView, o listener permanecerá na View antiga ao recriar. Solução: realize todo o trabalho relacionado a View em onViewCreated, deixando onCreate apenas para a inicialização da camada de dados.
Perguntas frequentes
Sim, sobrescrever onCreate é obrigatório para qualquer Activity que exiba uma interface do usuário. Sem isso, é impossível chamar setContentView e carregar o layout XML. Se a Activity não tiver UI (por exemplo, uma Activity stub transparente), onCreate ainda é sobrescrito, mas sem chamar setContentView.
Não, onCreate não pode ser chamado novamente para a mesma instância de Activity. Se a Activity for destruída e recriada (rotação de tela, falta de memória), é uma nova instância com uma nova chamada de onCreate. Uma exceção é o método recreate(), que força a destruição e recriação da Activity, mas isso é uma recriação de uma nova instância.
Se você não chamar super.onCreate(savedInstanceState), o Android Runtime lançará uma exceção SuperNotCalledException e o aplicativo travará. O sistema exige estritamente que cada método de ciclo de vida sobrescrito chame sua versão super — isso garante o funcionamento correto da máquina de estados interna.
A principal diferença: onCreate em Activity carrega a UI via setContentView, enquanto onCreate em Fragment apenas inicializa dados. Fragment cria a View em um método separado onCreateView, que pode ser chamado várias vezes (por exemplo, ao alternar abas), enquanto onCreate de Fragment é chamado uma vez durante o tempo de vida da instância do Fragment.
Os dados inicializados em onCreate são armazenados nos campos da classe Activity ou Fragment. Por exemplo, private lateinit var binding: ActivityMainBinding é declarado no nível da classe, inicializado em onCreate e disponível em todos os métodos subsequentes. Para dados que sobrevivem à rotação da tela, use ViewModel com LiveData ou StateFlow.
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