Saltar al contenido
K
Android: la plataformaPaso a paso38 min de lectura · 3 min de máquina Intermedio

El ciclo de vida de la Activity

Al terminar: Ver en Logcat cada callback de la Activity al arrancar, ir a Home y volver, y rotar, y saber por qué onDestroy no significa que el usuario se fue.

Al terminar esta lección, cada vez que Android cree, pause, oculte o destruya la pantalla de Marcador, dejará una línea en Logcat con el tag Ciclo. Verás con tus ojos qué llama el sistema y en qué orden. Parte de lo que dejó La Activity: :app ya depende de :torneo y Marcador ya corre en el emulador.

Importa porque todo lo que viene después (rotar, hilos, memoria) es una consecuencia de que el sistema decide cuándo empieza y acaba una pantalla, y tu código solo reacciona a sus avisos. Temas: la Activity y su ciclo de vida, callback a callback; Logcat; el error de creer que onDestroy significa «el usuario se fue».

El ciclo de vida, callback a callback

Dos palabras de la cita de abajo. finish es la orden con la que tu propio código cierra una pantalla (lo usarás en Intents explícitos y una segunda pantalla). Y un cambio de configuración es un cambio del entorno del dispositivo que afecta a la pantalla, como girar el móvil de vertical a horizontal; en Rotación y muerte del proceso lo verás con calma.

CallbackCuándo lo llama el sistemaLa pantalla está…
onCreateAl crearla (una vez por instancia)aún no visible
onStartJusto antes de hacerse visiblevisible, pero aún sin recibir toques
onResumeCuando ya puedes interactuardelante, con foco
onPauseAl perder el foco (otra pantalla encima, de otra app o de otra Activity)sin foco; puede verse todavía en parte (si lo que hay encima es transparente o de menor tamaño) o no
onStopCuando deja de verse del todooculta
onRestartAl volver desde onStop, antes de onStartoculta, a punto de verse
onDestroyAntes de destruirla (la cierra el usuario o tu código con finish, o la destruye el sistema)destruida

Dos aclaraciones sobre la tabla. Un diálogo de tu propia app (una ventanita de aviso) no cuenta como «otra pantalla encima»: es una ventana de la misma Activity, que sigue siendo la pantalla en primer plano, y por eso no sale ningún callback. Un diálogo del sistema (el que pide un permiso, por ejemplo) sí es otra pantalla, y sí dispara onPause. Y el botón Atrás en la pantalla principal de la app, desde Android 12, no llama a onDestroy: la manda al fondo, como Home. onDestroy llega cuando el usuario cierra una pantalla que no es la principal, cuando tu código llama a finish o cuando el sistema la destruye.

Dos palabras de esa tabla. Tener foco es ser la pantalla que recibe los toques y las teclas; visible es solo que se ve, aunque no reciba nada. Por eso hay un momento, entre onStart y onResume, en que la pantalla se ve pero no responde aún, y otro, en onPause, en que otra ventana ya tiene el foco pero la tuya sigue asomando por debajo. Y multiventana es el modo en que el sistema pone dos apps a la vez en la pantalla, cada una en una mitad; en ese modo la ventana sin foco sigue visible. En la documentación de Google verás que a una Activity que ya no se ve se le dice que está en estado STOPPED (parada): es solo una forma de hablar de lo que pasa tras onStop.

Hay dos callbacks más que no forman parte de esa escalera: onSaveInstanceState (el sistema te deja guardar datos antes de destruirla, es el tema de la próxima lección) y onRestoreInstanceState (te los devuelve). Y otros tres, más raros, que también sobrescribirás para verlos:

CallbackCuándo lo llama el sistema
onNewIntentLlega un Intent (un mensaje para abrir o dirigir una pantalla) a una Activity que ya existe. Hoy lo sobrescribes, pero no llegarás a dispararlo: se explica en Intents implícitos y filtros y se usa de verdad en Deep links en Android
onConfigurationChangedCambia la configuración (por ejemplo, la orientación) y el Manifest ha declarado que la Activity lo gestiona ella. Si no, no llega nunca
onTopResumedActivityChangedLa Activity gana o pierde el «primer plano» (útil en multiventana; existe desde Android 10, API 29)

La última fila habla de un nivel de API, el número que identifica cada versión de Android (Android 10 es la API 29, Android 9 la 28; lo viste en Instalar Android Studio y el SDK). Cuenta: siete de la primera tabla, onSaveInstanceState y onRestoreInstanceState del párrafo anterior, y tres de la segunda tabla. Son doce callbacks, y en Marcador sobrescribirás los doce.

Pruébalo antes de escribir código

Antes de tocar MainActivity, juega con el ciclo. Es tu ejercicio de esta lección, y se hace en tres tiempos. Primero predice, antes de pulsar nada, y apunta la respuesta en un papel:

  1. Si pulsas Home y vuelves a abrir la app, ¿qué callbacks saldrán, y en qué orden?
  2. Si rotas el móvil, ¿será la misma instancia de la pantalla (el mismo objeto) o una nueva? En el registro simulado lo sabrás por un código tras la @, un número que identifica a cada instancia: si cambia, es otra.
  3. Si abres un diálogo de tu propia app (una ventanita de aviso encima de la pantalla), ¿saldrá algún callback?

Después pruébalo: abre Marcador, ve a Home y vuelve, pon una pantalla encima, rota el móvil. Cada callback se enciende en la escalera (bajando a la izquierda, subiendo a la derecha) y se escribe en un registro simulado, con el mismo formato que verás luego en tu emulador. Con Paso a paso se ve además el momento, entre onStart y onResume, en que la pantalla ya se ve pero aún no recibe toques.

Laboratorio · ciclo de vida de una Activity
instancianinguna
M

Empieza abriendo Marcador desde su icono.

bajandoestadosubiendo
RESUMED · con foco
onPause ↓
↑onResume
STARTED · visible
onStop ↓
↑onRestart onStart
CREATED · oculta
onDestroy ↓
↑onCreate
sin instancia
fuera de la escaleraonSaveInstanceStateonRestoreInstanceStateonTopResumedActivityChanged
Logcat · tag:Ciclo
Una simulación: reproduce lo que tu Logcat escribe en el emulador, con el mismo formato.

Y por último compara con tus respuestas:

Ver solución
  1. Con Home salen onPause, onStop, onRestart, onStart y onResume, y la pantalla no se destruye.
  2. Al rotar, sí cambia el código tras la @: el sistema crea otra instancia.
  3. Un diálogo de tu propia app no dispara ningún callback: es una ventana de la misma Activity, que sigue en primer plano (ver las aclaraciones bajo la tabla).

Logcat: donde escribe tu app

Una app no tiene consola como el programa de :torneo: nadie ve su println. Para mirar qué hace por dentro, Android lleva un registro (un diario) donde escribe el sistema, las librerías y tu app, y Logcat es la herramienta que lo enseña. Log.d(tag, mensaje) escribe un mensaje de nivel Debug (depuración) con un tag (etiqueta) que eliges tú. El tag es el filtro para encontrar tus líneas entre miles del sistema. Aquí será Ciclo.

ejemplo mínimo: una línea en Logcat (con comentarios)
import android.util.Log   // la clase de Android que escribe en el registro
 
// Dentro de cualquier clase de la app:
Log.d("Ciclo", "onCreate")   // aparece en Logcat como «D Ciclo : onCreate»

Se ve de dos formas:

  1. En Android Studio, abriendo la ventana Logcat con View → Tool Windows → Logcat. Tiene un campo de búsqueda arriba: escribe tag:Ciclo y solo quedan las líneas con ese tag. Sin filtro verás muchísimas líneas del sistema, y es normal. Logcat solo muestra algo cuando hay una app ejecutándose en un emulador o un móvil: lo harás en el paso de abajo.
  2. En la terminal, con adb logcat -s Ciclo (-s significa «solo este tag»). adb es la herramienta que habla con el emulador; la instalaste en Instalar Android Studio y el SDK. Desde aquí y en todo el módulo vas a escribir órdenes de adb: están reunidas, con lo que hace cada una, en la Chuleta de adb del glosario. Ábrela en otra pestaña y vuelve a ella cuando una orden no te suene.

Error típico: creer que onDestroy significa «el usuario se fue»

onDestroy se llama en dos situaciones distintas (mira la cita de arriba). Si tu código asume la primera, se ejecutará también cuando el sistema solo está recreando la pantalla.

con el bug: onDestroy asume que se cierra la pantalla
override fun onDestroy() {
    super.onDestroy()
    anotar("el usuario ha terminado con la pantalla")   // falso al rotar
}

(anotar es el ayudante que escribirá cada línea en Logcat; lo escribes en el paso de abajo.)

corregido: preguntar por qué se destruye
override fun onDestroy() {
    super.onDestroy()
    // isFinishing es true si el usuario cierra; isChangingConfigurations, si es una recreación.
    anotar("onDestroy (isFinishing=$isFinishing, isChangingConfigurations=$isChangingConfigurations)")
}

Falla porque el sistema destruye y vuelve a crear la Activity cuando giras el móvil. En la salida real de más abajo, al rotar, onDestroy dice isFinishing=false, isChangingConfigurations=true.

Paso · Registra el ciclo en MainActivity

Objetivo: que MainActivity sobrescriba los doce callbacks del ciclo de vida y cada uno deje una línea en Logcat.

app → kotlin+java → com.sebastiannarvaez.marcador
MainActivity.ktse modifica: se añaden los callbacks
El fichero que se modifica, tal como lo ves en la vista Android: el mismo de la lección anterior.
  1. En la vista Android, despliega app → kotlin+java → com.sebastiannarvaez.marcador y haz doble clic en MainActivity.kt. Es la MainActivity que dejaste en La Activity: se queda como está, y le añades los callbacks.
  2. Los import los puedes escribir a mano o dejar que Android Studio los añada: con el cursor sobre un nombre en rojo, pulsa Option+Enter (Alt+Enter en Windows y Linux) y elige el import. Si te ofrece varios, elige el de androidx.

Piezas nuevas de este paso:

  • super.onXxx(…): llama al método de la clase madre, que hace su trabajo de base (por ejemplo, restaurar el estado de las vistas, los elementos de pantalla del sistema clásico de Android: botones, textos, imágenes). Va primero en todos los callbacks. En los del ciclo de vida, sin esa llamada Android lanza SuperNotCalledException; en los demás no avisa, pero se pierde lo que hace la clase madre.
  • Log.d(tag, mensaje); System.identityHashCode(this).toString(16): un número que identifica esta instancia de la Activity, en hexadecimal. Hexadecimal es otra forma de escribir números, con 16 cifras (del 0 al 9 y de la a a la f) en lugar de 10; aquí solo sirve para que el número sea corto, y c764bd7 es simplemente un nombre para esta instancia.
  • onSaveInstanceState(outState: Bundle) y onTopResumedActivityChanged(isTopResumedActivity: Boolean): dos de los doce callbacks con parámetros nuevos para ti. La firma de una función es su nombre más la lista de lo que recibe y devuelve; para sobrescribir un callback hay que copiarla exacta. El primero recibe un Bundle, el paquete donde guardas datos antes de que la Activity se destruya (el tema de la próxima lección); el segundo recibe un Boolean que dice si la Activity tiene el primer plano.
  • javaClass.simpleName: el nombre de la clase, MainActivity. isFinishing e isChangingConfigurations: propiedades de la Activity (ver el error típico).

Así se ven juntas esas piezas en una Activity de prueba, con otro callback y otra etiqueta que los de Marcador:

ejemplo mínimo: un callback sobrescrito y un ayudante (con comentarios)
class PruebaActivity : ComponentActivity() {           // hereda de la Activity de Jetpack
 
    override fun onPause() {                            // override: sustituye el método de la clase madre
        super.onPause()                                 // primero, el trabajo de base de la clase madre
        apuntar("onPause")                              // después, lo tuyo: una línea en Logcat
    }
 
    private fun apuntar(texto: String) {                // private: solo se usa dentro de esta clase
        val clase = javaClass.simpleName                // "PruebaActivity"
        val instancia = System.identityHashCode(this).toString(16)  // número de ESTA instancia, en hexadecimal
        Log.d("Prueba", "$clase@$instancia $texto")     // tag "Prueba"; se filtra con tag:Prueba
    }
}

Si pulsas Home con PruebaActivity en pantalla y filtras Logcat por tag:Prueba, la línea que sale es esta (el código tras la @ será otro):

D Prueba  : PruebaActivity@1a2b3c onPause

Escribir a mano doce métodos con la firma exacta es lento y fácil de equivocar, y nadie lo hace así: Android Studio los genera. Con el cursor dentro de la clase MainActivity (entre sus llaves, en una línea vacía), abre Code → Override Methods… (el atajo es Ctrl+O, con la tecla Control también en Mac). Sale una lista con todo lo que se puede sobrescribir: escribe el nombre para filtrarla, marca varios con Cmd+clic y pulsa OK. El IDE escribe cada override fun … con su firma correcta y la llamada a super; tú solo añades la línea anotar("…").

Intenta escribirlo tú:

  • Que cada callback de la primera tabla deje una línea en Logcat, con el tag Ciclo, que diga el nombre de la clase, el número de esta instancia y el nombre del callback.
  • Esa línea la escribe un método privado de la clase, anotar, que reciben todos.
  • onCreate ya está escrito: le añades su línea, que además dice si llegó estado guardado («no» la primera vez).
  • El resto los generas con el menú. Los otros cinco (onSaveInstanceState, onRestoreInstanceState, onNewIntent, onConfigurationChanged y onTopResumedActivityChanged) tienen firmas con tipos que aún no conoces: genéralos igual, o cópialos del bloque de abajo, que lleva los doce completos.

Lo que debes ver, cuando lo ejecutes en el paso siguiente: la tabla en pantalla y, en Logcat, estas tres líneas en este orden (el código tras la @ cambia en cada ejecución). En la ventana Logcat de Android Studio verás delante de cada línea la fecha, la hora y el nombre del paquete; el mensaje del final es el mismo:

D Ciclo   : MainActivity@c764bd7 onCreate (estado guardado: no)
D Ciclo   : MainActivity@c764bd7 onStart
D Ciclo   : MainActivity@c764bd7 onResume

El título del bloque de abajo es la ruta del fichero en tu proyecto; en la vista Android está en app → kotlin+java.

Intenta primero. Cuando termines, compara con la solución.Mostrar el código
app/src/main/java/com/sebastiannarvaez/marcador/MainActivity.kt
package com.sebastiannarvaez.marcador
 
import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.sebastiannarvaez.marcador.torneo.Ejemplo
 
// Una Activity es UNA pantalla que el sistema crea, pausa y destruye cuando
// quiere. No la construyes tu con `MainActivity()`: la crea Android, y te avisa
// de cada cambio llamando a estos metodos (los «callbacks» del ciclo de vida).
//
// Aqui cada callback deja una linea en Logcat con el tag `Ciclo`. Para verlas:
//   adb logcat -s Ciclo
// o en Android Studio: Logcat, y filtra por `tag:Ciclo`.
class MainActivity : ComponentActivity() {
 
    // `super.onXxx()` primero en todos: la clase madre hace su trabajo (por
    // ejemplo, restaurar el estado de las vistas) y `ComponentActivity` avisa a
    // Compose y a los componentes de Jetpack. Sin la llamada a `super`, Android
    // lanza SuperNotCalledException.
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        anotar("onCreate (estado guardado: ${if (savedInstanceState == null) "no" else "si"})")
 
        // Prueba de que `:app` ve el modulo `:torneo`: la tabla del torneo de ejemplo.
        val tabla = Ejemplo.torneoConPartidos().tablaDePosiciones()
        setContent {
            MaterialTheme {
                Column(Modifier.padding(24.dp)) {
                    Text("Marcador")
                    tabla.forEach { fila ->
                        Text("${fila.equipo.nombre}: ${fila.puntos} pts")
                    }
                }
            }
        }
    }
 
    override fun onStart() {
        super.onStart()
        anotar("onStart")
    }
 
    // Solo se llama al VOLVER a una Activity que estaba parada (no la primera vez).
    override fun onRestart() {
        super.onRestart()
        anotar("onRestart")
    }
 
    override fun onResume() {
        super.onResume()
        anotar("onResume")
    }
 
    override fun onPause() {
        super.onPause()
        anotar("onPause")
    }
 
    override fun onStop() {
        super.onStop()
        anotar("onStop")
    }
 
    override fun onDestroy() {
        super.onDestroy()
        // isFinishing: true si el usuario cierra la pantalla (atras); false si
        // el sistema la destruye (rotacion, falta de memoria).
        anotar("onDestroy (isFinishing=$isFinishing, isChangingConfigurations=$isChangingConfigurations)")
    }
 
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        anotar("onSaveInstanceState")
    }
 
    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        super.onRestoreInstanceState(savedInstanceState)
        anotar("onRestoreInstanceState")
    }
 
    // Solo llega si la Activity ya existe y le mandan un Intent nuevo.
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        anotar("onNewIntent")
    }
 
    // Solo se llama si el Manifest declara android:configChanges para ese cambio.
    // Sin esa declaracion, Android destruye y recrea la Activity y este callback
    // no llega nunca.
    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        anotar("onConfigurationChanged")
    }
 
    override fun onTopResumedActivityChanged(isTopResumedActivity: Boolean) {
        super.onTopResumedActivityChanged(isTopResumedActivity)
        anotar("onTopResumedActivityChanged($isTopResumedActivity)")
    }
 
    private fun anotar(mensaje: String) {
        // Log.d(tag, mensaje): nivel Debug. El tag es el filtro para encontrarlo.
        Log.d("Ciclo", "${javaClass.simpleName}@${System.identityHashCode(this).toString(16)} $mensaje")
    }
}

Paso · Arranca y lee las tres primeras líneas

Objetivo: ver en Logcat cómo empieza la vida de una Activity.

  1. Pulsa Run (con app en el selector de configuración y el emulador arrancado, como en La Activity). Android Studio reinstala la app encima de la anterior; tarda segundos. En la pantalla debe seguir la tabla de antes.
  2. Abre View → Tool Windows → Logcat. Escribe tag:Ciclo en el campo de búsqueda de arriba. Deben salir, de arriba abajo, onCreate (estado guardado: no), onStart y onResume, con el mismo código tras la @: así empieza la vida de una Activity.

Paso · Provoca el ciclo y léelo

Objetivo: ver en Logcat los callbacks de un arranque, de un «Home y volver» y de una rotación.

Provócalo en tres tandas. Antes de empezar, cierra la app del todo con adb shell am force-stop com.sebastiannarvaez.marcador, para que el siguiente arranque sea desde cero. El botón Atrás no sirve para esto: desde Android 12, en la pantalla principal de una app abierta desde su icono, Atrás no la destruye, la manda al fondo como Home (lo verás en el laboratorio de arriba). Los comandos de adb van desde la Terminal de Android Studio (o cualquier terminal) y están explicados en la Chuleta de adb:

  1. Vacía Logcat:
adb logcat -c
  1. A mano en el emulador: abre la app desde el icono, pulsa Home y vuelve a abrirla desde el icono (o desde la lista de apps recientes: en el emulador, el botón cuadrado de la barra de navegación, o deslizar hacia arriba desde abajo y mantener un momento; toca la tarjeta de Marcador).

  2. Gira el móvil con los botones del emulador. La barra de herramientas pegada al borde de la ventana del emulador tiene dos botones de giro: un icono de un móvil con una flecha curva, uno para girar a la izquierda y otro a la derecha (al pasar el ratón dice algo como «Rotate»). Púlsalo una vez: el móvil queda en horizontal. Después lee la salida:

adb logcat -d -s Ciclo

-d vuelca lo que ya hay y termina, y -s Ciclo deja solo el tag Ciclo (también puedes leerlo en la ventana Logcat de Android Studio con tag:Ciclo). Cuando termines de leerla, pulsa el otro botón de giro para dejar el móvil en vertical. Si no encuentras los botones, la Chuleta de adb trae las órdenes de settings que giran el móvil desde la terminal. Verás algo como esto con la versión de Android que tenga tu dispositivo virtual (aquí se han quitado la fecha y los números de proceso del principio de cada línea; los códigos tras la @ cambian en cada ejecución):

D Ciclo   : MainActivity@c764bd7 onCreate (estado guardado: no)
D Ciclo   : MainActivity@c764bd7 onStart
D Ciclo   : MainActivity@c764bd7 onResume
D Ciclo   : MainActivity@c764bd7 onTopResumedActivityChanged(true)
D Ciclo   : MainActivity@c764bd7 onTopResumedActivityChanged(false)
D Ciclo   : MainActivity@c764bd7 onPause
D Ciclo   : MainActivity@c764bd7 onStop
D Ciclo   : MainActivity@c764bd7 onSaveInstanceState
D Ciclo   : MainActivity@c764bd7 onRestart
D Ciclo   : MainActivity@c764bd7 onStart
D Ciclo   : MainActivity@c764bd7 onResume
D Ciclo   : MainActivity@c764bd7 onTopResumedActivityChanged(true)
D Ciclo   : MainActivity@c764bd7 onTopResumedActivityChanged(false)
D Ciclo   : MainActivity@c764bd7 onPause
D Ciclo   : MainActivity@c764bd7 onStop
D Ciclo   : MainActivity@c764bd7 onSaveInstanceState
D Ciclo   : MainActivity@c764bd7 onDestroy (isFinishing=false, isChangingConfigurations=true)
D Ciclo   : MainActivity@6929fbc onCreate (estado guardado: si)
D Ciclo   : MainActivity@6929fbc onStart
D Ciclo   : MainActivity@6929fbc onRestoreInstanceState
D Ciclo   : MainActivity@6929fbc onResume
D Ciclo   : MainActivity@6929fbc onTopResumedActivityChanged(true)

Tres cosas que leer ahí:

  • onSaveInstanceState sale después de onStop. Así ocurre desde Android 9 (API 28); antes se llamaba antes de onStop.
  • Al rotar, el código tras la @ cambia (c764bd7 → 6929fbc): es otra instancia. Y onCreate dice estado guardado: si, porque el sistema le entrega el paquete que guardó.
  • onConfigurationChanged no aparece. Solo se llamaría si el Manifest declarase android:configChanges para ese cambio; sin esa declaración el sistema recrea la Activity. onTopResumedActivityChanged (Android 10) no es del ciclo básico: sale porque hemos sobrescrito todos los callbacks. Entre los dos primeros onResume está lo que hizo tu Home: onPause, onStop, onRestart y onStart, con la misma instancia.

Un detalle del código: si no llamas a super en un callback del ciclo de vida (onCreate, onStart, onResume, onPause, onStop, onRestart, onDestroy), Android lanza SuperNotCalledException, según la documentación de las Activity. En los otros callbacks no salta ningún error, pero se pierde en silencio lo que hace la clase madre, por ejemplo guardar el estado de las vistas.

Punto de control

  • MainActivity.kt se abre sin nada en rojo, con sus doce callbacks, y ./gradlew :app:assembleDebug termina en BUILD SUCCESSFUL.
  • Run reinstala Marcador en el emulador y sigue mostrando «Marcador» y las cuatro líneas de equipo y puntos.
  • Logcat, con tag:Ciclo (o adb logcat -d -s Ciclo en la terminal), muestra onCreate (estado guardado: no), onStart y onResume con el mismo código tras la @, y al rotar, un código distinto.
  • Tras girar con los botones del emulador, Logcat muestra onDestroy (isFinishing=false, isChangingConfigurations=true) y el emulador vuelve a estar en vertical.

Comprueba lo que entendiste

6 preguntas · necesitas 5 para completar la lección

  1. 1.Abres la app, pulsas Home y vuelves a abrirla. ¿Cuáles de los callbacks del ciclo básico (los de la escalera, sin contar los de guardado) salen entre el primer onResume y el segundo?

  2. 2.Giras el móvil y en Logcat ves onDestroy (isFinishing=false, isChangingConfigurations=true). ¿Qué significa?

  3. 3.Quieres ver solo los mensajes que escribe tu Activity con Log.d("Ciclo", …). ¿Qué haces?

  4. 4.En Logcat ves que onSaveInstanceState sale justo después de onStop. ¿Es un error de tu código?

  5. 5.Giras el emulador con MainActivity sobrescribiendo onConfigurationChanged, pero ese callback no aparece en Logcat. ¿Por qué?

  6. 6.Sobrescribes onStart pero olvidas la línea super.onStart(). ¿Qué ocurre al ejecutar la app?

Faltan 6 de 6