Solución del problema de ADB "esperando dispositivo"


9

Estamos configurando un servidor de integración continua para nuestro desarrollo de Android y nos hemos encontrado rápidamente con el problema de ADB a la espera del dispositivo .

Para el registro, ya hemos probado muchas combinaciones de adb kill-server, adb start-server, adb devices, etc en vano.

Lamentablemente, todo lo que he encontrado en Internet son variaciones de "desconectar y volver a conectar el dispositivo", lo que obviamente no es una solución para nosotros (no podemos evitar que un ser humano se siente junto al servidor de CI para desconectar y volver a conectar dispositivos antes) cada construcción).

Como información básica, utilizamos Jenkins en una Mac, ya que también ejecuta nuestro CI para iOS.

Al abordar el problema, pensé que si en el nivel del sistema operativo se encuentra el dispositivo, eso es al menos un comienzo. De hecho, ejecutar un comando como system_profiler SPUSBDataTypeencuentra con éxito el dispositivo, incluido el número de serie que informa ADB cuando funciona correctamente.

He intentado algunos comandos poco convincentes para "actualizar" toda la actividad de USB, pero no he ido a ninguna parte. No es que pueda montar / desmontar el dispositivo, pero para ser honesto, ni siquiera estoy seguro de dónde está el problema, no sé lo suficiente sobre protocolos USB de bajo nivel, y mucho menos para Mac. Mi acecho del código fuente de ADB fue muy, muy lejano.

Por lo tanto, en este punto, soy todo oídos para una solución que nos permita ejecutar Android constantemente en nuestro servidor CI. Ya sea unos pocos comandos antes de cada trabajo de Jenkins, parcheando ADB o cualquier otro truco de magia negra.

Respuestas:


9

Encontré una manera de resolverlo, así que publica aquí para completar. Tenga en cuenta que no digo que esta sea la mejor manera de resolverlo, pero nos ha funcionado.

Entonces, nos dimos cuenta de que el problema ocurrió después de largos períodos de inactividad de CI (en el rango de horas). Entonces creamos un script simple que llama adb devicescada 10 segundos. Y el problema se ha ido, no más problemas de "esperar el dispositivo".

En Linux puedes hacer esto con un crontrabajo simple y en OSX con launchctly estoy seguro de que hay un equivalente de Windows.

De todos modos, "hacer ping" a los dispositivos cada 10 segundos lo resolvió para nosotros.


1
¡Gracias! Parece que estaba teniendo el mismo problema. Al desconectar y volver a enchufar el cable USB, el dispositivo apareció en la lista.
Jorge Pedret

5

Habilitado la depuración de USB (Configuración => Opciones de desarrollador) en el teléfono.


1

Tuvimos algunos problemas similares con nuestro entorno de Integración Continua con dispositivos Android desde una máquina OSX (también para iOS y Android).

Creo que el problema es que está permitiendo que Jenkins inicie el servidor adb. Esto causa problemas porque los trabajos de Jenkins están asociados con los depósitos que entran y salen de la existencia. Si Jenkins inicia el demonio adb con una llamada de "dispositivos adb" (por ejemplo), entonces el demonio adb será propiedad de un shell de Jenkins de corta duración, y cuando ese shell termine de ejecutarse y se cierre, el demonio adb se limpiará , hasta que otra llamada adb lo inicie automáticamente. Esto da como resultado un ciclo de inicio y detención del demonio adb, pero lo que quieres es que permanezca despierto indefinidamente.

Una forma de solucionar esto es simplemente ejecutar "dispositivos adb" desde un shell que se deja abierto en la máquina CI. Puede saber si es el proceso principal si este mensaje se muestra después de ejecutarse

blah$ adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
xxxxxxxxxxx          device

Este es un paso molesto que debe realizar cada vez que su máquina se reinicia, y si alguien cierra esa ventana de comandos, volverá al problema anterior.

En teoría, una mejor manera sería hacer un archivo .plist para activar el demonio adb en el arranque. Aquí hay un ejemplo: ~ / Library / LaunchAgents / server.adb.plist. Básicamente, esto solo ejecuta adb start-server desde el daemon de inicio del usuario para evitar que Jenkins sea el propietario.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>server.adb</string>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/Shared/Jenkins/android-sdk/platform-tools/adb</string>
        <string>start-server</string>
    </array>
  </dict>
</plist>

Sin embargo, el problema con esto es que solo inicia adb, pero no se bloquea, por lo que no puede usar la funcionalidad de control de inicio KeepAlive. Además, no parece funcionar para el propósito deseado. Si alguien conoce una forma de ejecutar adb en modo "daemon", para que no regrese, entonces este mecanismo de launchctl podría configurarse para reiniciarlo automáticamente si muere, asegurando así que Jenkins nunca obtenga la propiedad. Bueno, por ahora solo estaré ejecutando "dispositivos adb" en una ventana de shell y dejándolo abierto.


1

Resolví esto usando una regleta de alimentación programable para reiniciar los concentradores usb antes de cada ejecución de prueba. Esto hizo lo mismo que desconectar y volver a enchufar los cables usb.


¿Puedes expandir más?
Dinesh

1

Solo quería seguir la excelente sugerencia de juan-delgado . En MacOS High Sierra descubrí que ejecutar adbcada 10 segundos con el watchcomando también era efectivo como una solución rápida:

watch -n 10 adb -d devices

Esto me permite evitar crear un .plistarchivo, pero el inconveniente obvio es que no es una solución permanente. El watchcomando está disponible en versiones anteriores de OSX, por lo que también debería ser efectivo allí.


No tenía watchen macOS Catalina, pero pude instalarlo fácilmente brew install watch.
mokagio hace

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.