wandres.dev
ANDROID STUDIO · SDK, emulador y adb

Emuladores y dispositivos

Crear AVDs desde la línea de órdenes, entender la aceleración por hardware y las imágenes de sistema, y depurar en un dispositivo físico por USB y por wifi sin cables ni sorpresas.

⏱ 16 min

El emulador de Android tiene mala fama heredada de una época en la que era lento de verdad. Hoy, con virtualización nativa y una imagen de la arquitectura correcta, arranca en segundos y supera en fluidez a muchos teléfonos reales. Ese es justamente el problema: es tan bueno que invita a olvidar que no es un teléfono. Saber configurarlo bien y saber cuándo dejar de fiarte de él son la misma competencia vista desde dos lados.

🎯 Al terminar esta lección sabrás
  • Crear y gestionar AVDs desde el terminal, sin depender del IDE.
  • Elegir imagen de sistema y ABI con criterio, y verificar la aceleración por hardware.
  • Conectar un dispositivo físico por USB y por wifi, incluido el emparejamiento moderno.
  • Saber qué miente el emulador y qué solo se puede probar en hardware real.

Crear un AVD sin abrir la interfaz

Un AVD es un directorio con dos ficheros de configuración y una imagen de disco, nada más. Vive en ~/.android/avd, y todo lo que hace el diálogo gráfico se puede hacer con avdmanager, que es lo que querrás cuando montes un entorno reproducible.

sdkmanager --install "system-images;android-36;google_apis;arm64-v8a"

avdmanager list device | head -20
avdmanager create avd -n Pixel8_API36 \
  -k "system-images;android-36;google_apis;arm64-v8a" \
  -d pixel_8

emulator -list-avds
emulator -avd Pixel8_API36 -gpu host -memory 4096 -no-boot-anim

La elección de imagen de sistema no es cosmética. La variante default es AOSP puro, sin servicios de Google. google_apis añade los servicios de Play y, lo que importa más, permite adb root, con lo que puedes leer el almacenamiento privado de cualquier aplicación. google_apis_playstore incluye la tienda pero está bloqueada y no admite root, así que solo la quieres cuando pruebes compras o servicios que exijan un dispositivo certificado. Y las imágenes atd, sin interfaz gráfica ni aplicaciones preinstaladas, arrancan mucho más rápido y son las adecuadas para pruebas instrumentadas en integración continua.

Fichero Contenido
config.ini Perfil de hardware editable: RAM, densidad, tamaño de pantalla, cámaras
hardware-qemu.ini Lo que QEMU usó realmente en el último arranque, generado
userdata-qemu.img La partición de datos, lo que -wipe-data destruye
snapshots/ Los estados congelados que permiten el arranque rápido

Aceleración por hardware

El emulador no interpreta instrucciones: virtualiza. Por eso su rendimiento depende por completo de que el sistema anfitrión le dé acceso al hipervisor, y por eso una imagen con la ABI equivocada lo arruina todo. En un portátil con procesador ARM, una imagen x86_64 obliga a traducir cada instrucción y el resultado es exactamente la lentitud legendaria de hace diez años.

emulator -accel-check          # diagnostico en una linea

# Linux: KVM. El usuario debe pertenecer al grupo correspondiente
ls -l /dev/kvm
sudo usermod -aG kvm "$USER"

# arranque en frio cuando el estado guardado se ha corrompido
emulator -avd Pixel8_API36 -no-snapshot-load
emulator -avd Pixel8_API36 -wipe-data

El binario del emulador acepta decenas de banderas, pero solo un puñado cambia la vida a diario.

Bandera Para qué sirve
-gpu host Delega el renderizado en la GPU del anfitrión: la opción rápida
-gpu swiftshader_indirect Renderizado por software, para servidores sin tarjeta gráfica
-no-window Sin ventana, imprescindible en integración continua
-no-snapshot-load Arranque en frío, ignorando el estado guardado
-wipe-data Restablece la partición de datos como si fuera nueva
-writable-system Permite remontar la partición de sistema en modo escritura
-netdelay gprs -netspeed edge Arranca ya con una red lenta simulada

En macOS la aceleración usa el hipervisor del sistema y no requiere instalar nada; en Windows se apoya en la plataforma de hipervisor, que hay que activar como característica del sistema y que convive mal con otros virtualizadores. La regla mnemotécnica es simple: la ABI de la imagen debe coincidir con la del anfitrión. Además, el emulador guarda instantáneas al cerrarse para arrancar en caliente; cuando el emulador se comporta de forma inexplicable, un arranque en frío resuelve más problemas que cualquier otra medida.

💡
Snapshots como estado de partida

Puedes preparar un emulador con sesión iniciada, permisos concedidos y datos de prueba, guardar la instantánea y arrancar siempre desde ese punto. Es la forma más barata de tener un entorno determinista para pruebas manuales repetitivas.

Un dispositivo físico, por cable y por aire

El camino empieza igual desde hace quince años: en los ajustes del teléfono, pulsar siete veces sobre el número de compilación desbloquea las opciones de desarrollador. Dentro, la depuración por USB es lo que arranca el demonio en el dispositivo. Al conectar, el teléfono muestra un diálogo con la huella RSA de tu ordenador: esa autorización es un intercambio de claves, y si adb devices dice unauthorized, el diálogo se rechazó o nunca apareció.

adb devices -l                       # el sufijo -l muestra modelo y producto
adb kill-server && adb start-server  # cuando el listado se queda pegado

# Depuracion inalambrica moderna, sin cable en ningun momento
adb pair 192.168.1.42:37105          # pide el codigo de seis digitos del telefono
adb connect 192.168.1.42:39221

# Metodo antiguo, requiere un cable para el primer paso
adb tcpip 5555
adb connect 192.168.1.42:5555
adb usb                              # volver al modo cable

El emparejamiento inalámbrico moderno usa dos puertos distintos y aleatorios: uno para emparejar y otro para conectar, ambos visibles en la pantalla de depuración inalámbrica del teléfono. Conviene saber que la conexión por red se pierde cuando el teléfono cambia de subred o entra en suspensión profunda, y que reconectar es barato pero no automático.

En Linux hay un obstáculo adicional que ninguna guía oficial subraya lo suficiente: sin una regla de udev que dé permiso a tu usuario sobre el identificador de fabricante del dispositivo, adb lo verá como no permissions aunque el cable esté perfecto.

lsusb                                   # localiza el idVendor de tu fabricante
sudo tee /etc/udev/rules.d/51-android.rules > /dev/null <<'EOF'
SUBSYSTEM=="usb", ATTR{idVendor}=="04e8", MODE="0660", GROUP="plugdev"
EOF
sudo udevadm control --reload-rules && sudo udevadm trigger
flowchart TD
A[Que necesito probar] --> B{Depende del hardware real}
B -- No --> C[Emulador con imagen de la ABI del anfitrion]
B -- Si --> D[Dispositivo fisico]
C --> E[Iteracion rapida y estados reproducibles]
D --> F[Camara y sensores y termico y GPU real]
D --> G[Gama baja para medir el peor caso]
style C fill:#89b4fa,color:#11111b
style D fill:#f9e2af,color:#11111b

Lo que el emulador no puede contarte

El emulador es un dispositivo virtual completo, con su kernel y su sistema de ficheros, pero corre sobre un anfitrión con recursos abundantes y sin batería que agotar. De ahí nace una lista de mentiras sistemáticas: no hay estrangulamiento térmico, así que un bucle costoso que en un teléfono real bajaría la frecuencia del procesador aquí se ejecuta a velocidad constante; la GPU es la de tu ordenador con sus controladores de escritorio, y los fallos de renderizado específicos de un fabricante no aparecen; la cámara es una escena sintética; los sensores son valores que tú inyectas; la presión de memoria casi nunca llega al punto en que el sistema mata procesos, que es precisamente el escenario que rompe las aplicaciones mal diseñadas.

A cambio, el emulador ofrece algo que ningún teléfono real permite: una consola de control que inyecta condiciones imposibles de provocar a mano.

adb emu gsm call 600123456          # llamada entrante mientras grabas video
adb emu gsm voice unregistered      # quedarse sin cobertura
adb emu network delay gprs          # latencia de una red de hace veinte anios
adb emu power capacity 3            # bateria al tres por ciento
adb emu finger touch 1              # huella dactilar aceptada
adb emu geo fix -3.70 40.41         # situarte en unas coordenadas concretas

Esa asimetría define el reparto de tareas: el emulador es insuperable para probar caminos raros de forma reproducible, y el hardware real es insustituible para saber cómo se siente la aplicación.

Optimizas para el dispositivo en el que pruebas, lo sepas o no

Existe un sesgo silencioso que degrada la calidad de las aplicaciones Android de forma casi universal, y consiste en que quien las escribe las prueba en un teléfono caro o en un emulador que corre sobre una máquina de desarrollo. El resultado es medible: aplicaciones que van bien en el uno por ciento superior del parque de dispositivos y que en la mediana real —cuatro gigabytes de RAM, almacenamiento lento, procesador de dos generaciones atrás, la memoria repartida entre quince aplicaciones abiertas— tardan seis segundos en arrancar y pierden el estado cada vez que el usuario contesta un mensaje. La causa no es negligencia sino física: la retroalimentación que recibes durante el desarrollo procede del entorno en el que ejecutas, y ese entorno define implícitamente lo que te parece aceptable. Si nunca ves una animación entrecortada, nunca escribirás código para evitarla. Si tu proceso jamás muere en segundo plano porque tu emulador tiene ocho gigabytes libres, jamás descubrirás que tu pantalla de detalle no restaura su estado. La disciplina correcta no es dejar de usar el emulador, que es una herramienta magnífica para iterar, sino construir un bucle de verificación en dos capas: desarrollo rápido en emulador, y una verificación periódica y obligatoria en el peor hardware que puedas conseguir, con las opciones de desarrollador ajustadas para simular hostilidad —no conservar actividades, límite de procesos en segundo plano, escalas de animación al doble para ver lo que normalmente pasa demasiado rápido—. Un teléfono barato de segunda mano sobre la mesa es la inversión con mejor retorno que puede hacer un equipo Android, porque convierte una clase entera de errores invisibles en errores evidentes.

⚔️ Monta tu banco de pruebas
  1. Crea dos AVDs desde el terminal con avdmanager: uno google_apis para desarrollo y uno atd para pruebas. Compara sus tiempos de arranque.
  2. Verifica la aceleración con emulator -accel-check y comprueba que la ABI de tus imágenes coincide con la de tu procesador.
  3. Prepara un emulador con datos de prueba y permisos concedidos, guarda la instantánea y demuestra que arranca en ese estado.
  4. Conecta un dispositivo físico por USB, autoriza la huella y luego pásalo a inalámbrico con adb pair sin volver a usar el cable.
  5. Activa “no conservar actividades” y el límite de procesos en segundo plano en el dispositivo real, y anota todo lo que se rompe en tu aplicación.
  6. Ejecuta la misma pantalla en el emulador y en el peor teléfono que tengas a mano, y mide la diferencia de tiempo hasta el primer fotograma útil.