Depuración remota con emulador de Android

94

¿Es posible escribir el código / compilar la aplicación de Android en una máquina y depurarla de forma remota en el emulador lanzado en otra? Estoy harto y cansado de que el emulador se coma constantemente la mitad de la CPU de mi computadora portátil.

zakovyrya
fuente

Respuestas:

72

No he probado anteriormente (ni siquiera noté) el adb connectcomando que mencionó cmb, pero puedo confirmar que reenviar los puertos TCP usted mismo, como por SSH, funciona bien.

El emulador escucha en dos puertos TCP por instancia: 5554 para la interfaz telnet y 5555 para controlar la comunicación con herramientas como DDMS. Así que probablemente podría salirse con la suya con solo reenviar el puerto 5555 (aunque solo lo he probado hasta ahora con ambos). Cada emulador posterior toma la siguiente tupla de número de puerto par + impar disponible (hasta alrededor de 5580, creo).

Como referencia, hice los siguientes pasos en mi máquina local:

  • ssh -NL 5554:localhost:5554 -L 5555:localhost:5555 myuser@remote-server
  • killall adb; adb devices

Creo que el emulador intenta notificar a un servidor adb local al inicio; de ahí la necesidad de reiniciar adb para que pruebe los puertos locales 5554+.

Tenga localhosten cuenta que el comando ssh se refiere a la interfaz local de la máquina remota .

adb devicesmostró un nuevo emulador - emulator-5554- y pude usarlo como si se estuviera ejecutando en mi máquina local.

Christopher Orr
fuente
1
funciona como un encanto, incluso desde mi máquina con Windows 7 con reenvío de puertos SSH de Putty. Gracias.
gsbabil
1
@JimMcKeeth: Según la configuración de red anterior, abra Putty, vaya a Conexión> SSH> Túneles. Ahora agregue una entrada con Source-port: 5556 y Destination: localhost: 5554. Repita lo mismo con Source-port: 5557 y Destination: localhost: 5555. ¡Salud!
gsbabil
5
Solo recuerde que también debe killall adbhacerlo en el servidor, porque el emulador no aceptará múltiples conexiones y será offlinepara la máquina local.
Henrique de Sousa
¿Alguien puede explicarlo en inglés?
Anil GR
21

Así es como lo resolví en Windows. Seguí bastante el ejemplo de Christopher, pero no puedo editar, así que una nueva respuesta tendrá que ser suficiente.

El problema que tuve fue que ADB, así como el emulador, solo escuchaban en 127.0.0.1, no en 0.0.0.0, para mí. De lo contrario, habría usado TCPMon . Supongo que esto es diferente en Windows o ha cambiado con las últimas versiones del SDK. (Puede consultar con netstat -ban.)

  1. Instalé WinSSHD en la máquina que ejecuta el emulador. (Creo que también debería funcionar con freeSSHd, pero no pude hacer que un inicio de sesión funcionara allí).

  2. Abrí el puerto 22 (TCP) en el Firewall de Windows. (Es posible que WinSSHD pueda hacer eso por usted).

  3. Creé una cuenta virtual en la GUI de WinSSHD.

  4. Creé una nueva conexión PuTTY desde la máquina de desarrollo a la máquina emuladora y me aseguré de poder conectarme.

  5. Luego configuré el túnel en PuTTY: Conexión -> SSH -> Túneles

    Source port: 5554
    Destination: localhost:5554
    Type: Local/Auto

    Source port: 5555
    Destination: localhost:5555
    Type: Local/Auto

    (Conecte y mantenga PuTTY abierto para mantener el túnel).

  6. Ahora encendí el emulador en la máquina remota y me aseguré de que ADB no se estuviera ejecutando allí.

  7. Reinicié ADB en la máquina de desarrollo ( adb kill-server, luego adb start-server).

  8. adb devicesy el emulador remoto apareció como emulator-5554 device. Ahora podía implementar y ejecutar mi aplicación directamente desde Eclipse / ADT, donde el emulador aparecía en Dispositivos virtuales como si fuera un emulador local.

Henrik Heimbuerger
fuente
¡Funcionó muy bien! Gracias por los detalles.
Jim McKeeth
1
Bien, pero me gustaría aclarar: después del paso 4 tienes que cerrar la masilla, luego en el paso 5 abrirla de nuevo, configurar los túneles y volver a conectar. Pasos 6-8: primero inicie el emulador, luego inicie adb (en la máquina host). Paso 9: es posible que desee reiniciar adb en la máquina cliente y escribir adb devices para asegurarse de que esté bien. Las cosas regulares de DDMS y eclipse también deberían funcionar.
Mister Smith
@MisterSmith Puntos muy válidos, ¿por qué no envían una edición? :)
Henrik Heimbuerger
@MisterSmith ¿Puede editar su respuesta para reflejar este comentario? Es muy importante para el éxito del problema. Además, gracias, ahora puedo conectarme a mi host desde mi máquina invitada.
meanbunny
21

Me doy cuenta de que esta pregunta es realmente antigua, pero resolví el problema de manera ligeramente diferente y me tomó un tiempo descubrir esta solución trivial.

Por lo general, uso una PC o computadora portátil con Windows7 (dependiendo de dónde esté trabajando) como mi interfaz porque me gusta la GUI, sin embargo, prefiero hacer toda mi edición / compilación / depuración en un servidor Ubuntu sin cabeza debido a todas las el poder de línea de comandos que proporciona. Mi objetivo es hacer que cada sistema de Windows sea lo más cliente ligero posible sin servicios adicionales (como sshd) o agujeros de firewall.

Entonces aquí está el senario:

  • System-A: sistema Windows7 con emulador de Android en ejecución
  • System-B: servidor Ubuntu con SDK instalado

El problema, como se describió anteriormente, es que el emulador en System-A se une a localhost, no a la interfaz Ethernet externa, por lo que adb en System-B no puede acceder al emulador en System-A. Todo lo que necesita hacer es configurar el reenvío de puerto remoto en PuTTY para su conexión SSH a System-B. El truco consiste en marcar el botón de opción "Remoto" cuando crea los dos túneles para que la dirección del túnel se invierta (tunelización desde el servidor en el que está iniciando sesión hasta el cliente desde el que está iniciando sesión).

captura de pantalla del túnel

Finalmente, conéctese con adb a "localhost" en System-B después de establecer la conexión SSH:

System-B$ adb connect localhost
connected to localhost:5555
System-B$ adb devices
List of devices attached
localhost:5555  device

Ahora puede descargar imágenes / depurar como de costumbre, y es una cuestión trivial cambiar a un sistema Windows diferente si desea sacar su computadora portátil y tomar un café.

Además, al hacer un túnel en el puerto 5037 de la misma manera, puede reenviar la conexión del servidor adb para que pueda conectar un dispositivo Android real a través de USB en el Sistema-A y descargar imágenes desde el Sistema-B. Para que esto funcione, debe asegurarse de que el servidor adb se esté ejecutando en System-A y no en System-B antes de comenzar su sesión SSH:

Primero, inicie el servidor adb en System-A (símbolo del sistema)

C:\> adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
C:\> adb devices
List of devices attached
3435F6E6035B00EC        device

A continuación, elimine el servidor adb en System-B

System-B$ adb kill-server

Finalmente, reinicie su sesión ssh en System-B y verifique

System-B$ adb devices
List of devices attached
3435F6E6035B00EC        device
Patrick McKinnon
fuente
¿Hay alguna forma de hacer esto sin instalar el sdk de Android en System-A? (¿La máquina de Windows?)
Keith Twombley
No, porque el servidor adb y los controladores USB deben ejecutarse en el Sistema-A para comunicarse con el dispositivo.
Patrick McKinnon
También hice esto con una configuración como: Windows 7 (emulador en ejecución) -> Linux (salto requerido, debido a la red ...) -> OS X ejecutando Eclipse. Puedo ver los dispositivos con 'dispositivos adb' y usar el emulador de Eclipse. El problema es que no reconoce el objetivo de Android del emulador, por lo que debo seleccionar el objetivo en cada ejecución manualmente.
Frank
si necesita una masilla para Mac OS X, la puede encontrar aquí: mac-tools.org/putty-fur-mac-os-x/02/2012 Para mí funcionó con esa herramienta.
Bruno Bieri
@PatrickMcKinnon la cosa funcionó bien, pero en System-B, no estoy autorizado al llamar a "dispositivos adb". En el System-B "adb devices" muestra que funciona bien. ¿Alguna ayuda?
Tejas Sherdiwala
6

Encontré una manera fácil de hacer esto si sus dos máquinas están en la misma red privada y, por lo tanto, no necesitan usar el cifrado SSH (que es el caso común). Esto puede ayudar, ya que un túnel SSH puede ser bastante largo y difícil de instalar. Por ejemplo, instalar un demonio SSH bajo Cygwin / Windows por primera vez puede llevar a rendirse (bueno, me rendí).

En Windows, lo que sigue requiere tener Cygwin instalado con el paquete httptunnel . Esto también debe funcionar en Linux / httptunnel , pero no lo intenté.

  • Ejecute el emulador en una de las máquinas (digamos que su nombre de host es HostEmulator )

  • Inicie Eclipse en la otra máquina (llamémoslo HostEclipse )

  • Abra una terminal Cygwin en cada máquina y luego,

  • En HostEmulator , ingrese los siguientes comandos cygwin :

    hts -F localhost:5554 10000
    hts -F localhost:5555 10001
    

hts significa Http Tunnel Server .

Estos dos comandos crean dos medio puente que escuchan los puertos 10001 y 10001 y que redirigen la E / S de estos puertos a los puertos locales 5554 y 5555, que son los puertos utilizados por el emulador (en realidad, el primer emulador lanzado - si son varios de ellos en ejecución, utilizarán números de puerto más altos, como se ve en otras respuestas de esta página).

  • En HostEclipse , ingrese estos :

    htc -F 5554 HostEmulator:10000
    htc -F 5555 HostEmulator:10001
    

htc significa Http Tunnel Client .

Estos comandos crean los medios puentes que faltan. Escuchan los puertos locales 5554 y 5555 y redirigen la E / S de estos puertos a los medios puentes que hemos creado en HostEmulator justo antes.

  • Luego, aún en HostEclipse , ingrese estos tres comandos :

    adb kill-server
    adb start-server
    adb devices
    

Esto reinicia adb ya que de lo contrario no detecta el emulador remoto. Debe estar escaneando al inicio. Y luego enumera los dispositivos (los emuladores disponibles) solo para verificar.

  • Y ahí tienes.

Puede trabajar con su emulador remoto como si fuera local. Tienes que mantener las terminales Cygwin abiertas en ambas máquinas, de lo contrario matarías los medios puentes que creaste.

Usé el puerto 10000 y 10001 para los intercambios de máquina / máquina aquí, pero por supuesto puede usar otros puertos siempre que no estén en uso.

Shlublu
fuente
2

Mi solución para Windows + AndroVM (que requiere un adaptador solo de host) cuando mi servicio ssh no se pudo iniciar. por lo que no requiere ningún software adicional.

adb connect <Andro VM IP>
adp tcpip 555

En el indicador de cmd, ejecute como administrador:

netsh interface portproxy add v4tov4 listenport=5555 listenaddress=<host ip> connectport=5555 connectaddress=<Andro VM IP>

Abra el puerto TCP 5555 en el firewall de Windows.

Luego, desde la segunda PC ejecute:

adb connect <host ip>
Emirikol
fuente
1

Ninguna de las soluciones propuestas funcionó para mí. Comencé con la solución de Emirikol y la refiné, ya que con la nueva API de Android> 21 el emulador aparecía sin conexión y tuve que ir a la configuración de Genymotion y dejar la ruta del SDK de Android vacía. Y desde la línea de comando:

netsh interface portproxy add v4tov4 listenport=5555 connectport=5555 connectaddress=<emulatorIP>

netsh interface portproxy add v4tov4 listenport=5554 connectport=5554 connectaddress=<emulatorIP>

fuente: http://www.sarpex.co.uk/index.php/2016/10/02/connect-genymotion-emulator-remotely/ Descargo de responsabilidad, soy el autor.

Sarpe
fuente
¡Respuesta y artículo perfectos! Si usa Genymotion, use esta solución. El artículo está escrito sobre Windows y Mac, pero tengo Ubuntu local y Ubuntu remoto y todo funciona bien. ¡Salvó mi semana!
konstantin_doncov
1

Cuando ejecuta adb, inicia una copia del servidor de sí mismo si aún no se está ejecutando. Puede iniciar esa copia usted mismo en la máquina con el dispositivo y, desde sdk 4.3, puede darle la opción -a para decirle a ese servidor que escuche máquinas remotas. Hazlo con el siguiente comando que no sale:

adb -a -P 5037 servidor nodaemon

En la máquina desde la que desea usar el dispositivo, configure ADB_SERVER_SOCKET en tcp: xxxx: 5037 en una variable de entorno (o dé el mismo valor a cada invocación de adb con la opción -L), donde xxxx es la dirección IP o el nombre de host del máquina con los dispositivos, y 5037 coincide con el puerto que proporcionó en el comando anterior.

Usamos esto para dar acceso a aproximadamente 100 emuladores distribuidos en 3 máquinas a una máquina que ejecuta pruebas de extremo a extremo en paralelo, y a los desarrolladores que desean compartir dispositivos reales de forma remota.

Puede reenviar puertos hacia y desde el emulador con adb forward y adb reverse, y aparecerán en la máquina con los dispositivos (no en la máquina desde la que está ejecutando 'adb forward').

android.weasel
fuente
¿Puede proporcionar más detalles sobre esta solución? Hice todo lo que dijiste, pero no tengo ningún dispositivo en "Seleccionar destino de implementación" en Android Studio. Utilizo Genymotion en la segunda computadora.
konstantin_doncov
@ don-prog No dice si funciona para usted desde la línea de comandos: adb -L tcp:remotehost:1234 devicessi lo hace, entonces debe averiguar si Android Studio admite ADB remotos o no; no me sorprendería si insiste en usar dispositivos locales.
android.weasel
0

No tengo una segunda máquina con el SDK a mano, pero noto que los puertos de escucha del emulador (por defecto 5554, 5555) están escuchando 0.0.0.0 , es decir, accesibles desde máquinas remotas, y eso adb --helpmuestra un connect <host>:<port>comando. Supongo que eso haría que se mostrara adb devicespara que los adbcomandos funcionen en él. Para Eclipse, intente "Ejecutar / Ejecutar configuraciones ..." y establezca el Destino en Manual. Eso le da un "selector de dispositivo" que supongo que incluiría un emulador remoto si adb está conectado a él. Vale la pena intentarlo.

Chris Boyle
fuente