¿Por qué importa el ciclo de vida?

Android puede destruir y recrear tu Activity en cualquier momento: al rotar el dispositivo, cuando el sistema necesita memoria, o cuando el usuario cambia de app. Si no manejás el ciclo de vida correctamente, tu app va a tener bugs difíciles de reproducir: datos perdidos al rotar, memory leaks, crashes en background.

Entender el ciclo de vida es la diferencia entre una app estable y una que crashea.

Los métodos del ciclo de vida

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // La Activity se crea. Inflá el layout, inicializá variables,
        // configurá listeners. Se llama una sola vez (o al recrearse).
    }

    override fun onStart() {
        super.onStart()
        // La Activity es visible pero aún no interactuable.
        // Poco usado en la práctica.
    }

    override fun onResume() {
        super.onResume()
        // La Activity está en primer plano y el usuario puede interactuar.
        // Iniciá animaciones, sensores, cámara, actualizaciones de UI.
    }

    override fun onPause() {
        super.onPause()
        // Otra Activity va a tomar el foco (dialog, nueva pantalla).
        // Pausá animaciones, liberá recursos que consumen batería.
        // Guardá datos críticos acá (puede ser el último método llamado).
    }

    override fun onStop() {
        super.onStop()
        // La Activity ya no es visible. Liberá recursos pesados.
        // No hagas operaciones largas acá: el sistema puede matarte.
    }

    override fun onDestroy() {
        super.onDestroy()
        // La Activity se va a destruir definitivamente.
        // Liberá todo lo que quede: listeners, conexiones, etc.
    }
}

Flujos típicos

  • App se abre por primera vez: onCreate → onStart → onResume
  • Usuario presiona Home: onPause → onStop
  • Usuario vuelve a la app: onRestart → onStart → onResume
  • Usuario rota el dispositivo: onPause → onStop → onDestroy → onCreate → onStart → onResume
  • Usuario presiona Back: onPause → onStop → onDestroy

La rotación recrea la ActivityCuando el usuario rota el dispositivo, Android destruye y recrea la Activity. Todo lo que guardaste en variables de instancia se pierde. Esto sorprende a muchos devs nuevos.

Guardar estado con savedInstanceState

Para guardar datos simples ante la recreación, usás onSaveInstanceState:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putString("TEXTO_USUARIO", binding.etNombre.text.toString())
    outState.putInt("CONTADOR", contador)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    // Si existe savedInstanceState, la Activity se está recreando
    savedInstanceState?.let {
        binding.etNombre.setText(it.getString("TEXTO_USUARIO"))
        contador = it.getInt("CONTADOR")
    }
}

La solución moderna: ViewModel

Para datos más complejos, la solución moderna es el ViewModel. Un ViewModel sobrevive a las recreaciones de la Activity (rotaciones, cambios de configuración) y limpia sus recursos cuando la Activity se destruye definitivamente.

// ViewModel
class MainViewModel : ViewModel() {
    var contador = 0
    var nombre = ""
}

// Activity
class MainActivity : AppCompatActivity() {
    // viewModels() crea el ViewModel y lo reutiliza si ya existe
    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // viewModel.contador persiste aunque rotes el dispositivo
    }
}

Regla prácticaUsá savedInstanceState para estado de UI pequeño (texto en un campo, posición de scroll). Usá ViewModel para datos de la pantalla (resultados de una llamada a la API, lista de items).