Contournement du problème «en attente de périphérique» ADB


9

Nous mettons en place un serveur d'intégration continue pour notre développement Android et nous avons rapidement rencontré ADB en attente de problème de périphérique .

Pour mémoire, nous avons déjà essayé beaucoup de combinaisons adb kill-server, adb start-server, adb devices, etc. en vain.

Malheureusement, tout ce que j'ai trouvé sur Internet sont des variantes de "débrancher et rebrancher l'appareil", ce qui n'est évidemment pas une solution pour nous (nous ne pouvons pas épargner à un être humain de s'asseoir près du serveur CI pour débrancher et rebrancher des appareils avant chaque build).

En guise de contexte, nous utilisons Jenkins sur un Mac, car il exécute également notre CI pour iOS.

En abordant le problème, j'ai pensé que si au niveau du système d'exploitation l'appareil était trouvé, c'était au moins un début. En effet, l'exécution d'une commande comme system_profiler SPUSBDataTyperéussit à trouver l'appareil, y compris le numéro de série que ADB signale lorsqu'il fonctionne correctement.

J'ai essayé quelques commandes plutôt boiteuses pour "rafraîchir" toutes les activités USB, mais je ne suis allé nulle part. Ce n'est pas que vous puissiez monter / démonter l'appareil, mais pour être honnête, je ne sais même pas où est le problème, je ne connais pas assez les protocoles USB de bas niveau, encore moins pour les Mac. Ma cachette du code source ADB était un très, très long coup.

Donc, à ce stade, je suis à l'écoute d'une solution qui nous permettrait d'exécuter constamment Android sur notre serveur CI. Que ce soit quelques commandes avant chaque travail Jenkins, patcher ADB ou tout autre tour de magie noire.

Réponses:


9

J'ai trouvé un moyen de le résoudre, alors postez ici pour être complet. Veuillez noter que je ne dis pas que c'est la meilleure façon de le résoudre, mais cela a fonctionné pour nous.

Nous avons donc réalisé que le problème s'était produit après de longues périodes d'inactivité de l'IC (dans la plage d'heures). Nous avons donc créé un script simple qui appelle adb devicestoutes les 10 secondes. Et le problème a disparu, plus de problèmes "en attente de périphérique".

Sous Linux, vous pouvez le faire avec un crontravail simple et sous OSX avec launchctlet je suis sûr qu'il existe un équivalent Windows.

Quoi qu'il en soit, le "ping" des appareils toutes les 10 secondes l'a résolu pour nous.


1
Merci! On dirait que j'avais le même problème. Débrancher et rebrancher le câble USB a fait apparaître l'appareil dans la liste.
Jorge Pedret

5

L'activation du débogage USB (Paramètres => Options développeur) dans le téléphone a aidé.


1

Nous avons eu des problèmes similaires avec notre environnement d'intégration continue avec des appareils Android à partir d'une machine OSX (également utilisé pour iOS et Android).

Je crois que le problème est que vous autorisez Jenkins à démarrer le serveur adb. Cela cause des problèmes car les emplois Jenkins sont associés à des coquilles qui entrent et sortent de l'existence. Si Jenkins lance le démon adb avec un appel "adb devices" (par exemple), alors le démon adb appartiendra à un shell Jenkins de courte durée, et lorsque ce shell aura terminé son exécution et se fermera, le démon adb sera nettoyé , jusqu'à ce qu'il soit redémarré automatiquement par un autre appel adb. Cela se traduit par un cycle de démarrage et d'arrêt du démon adb, mais ce que vous voulez, c'est qu'il reste juste indéfiniment.

Une façon de résoudre ce problème est d'exécuter simplement des "périphériques adb" à partir d'un shell qui reste ouvert sur la machine CI. Vous pouvez dire s'il s'agit du processus parent si ce message s'affiche après l'exécution

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

Il s'agit d'une étape ennuyeuse à effectuer à chaque redémarrage de votre machine, et si quelqu'un ferme cette fenêtre de commande, vous reviendrez au problème précédent.

En théorie, une meilleure façon serait de créer un fichier .plist pour déclencher le démon adb au démarrage. Voici un exemple: ~ / Library / LaunchAgents / server.adb.plist. Cela exécute simplement adb start-server à partir du démon de lancement utilisateur pour éviter que Jenkins ne le possède.

<?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>

Le problème avec cela, cependant, est qu'il ne fait que démarrer adb, mais qu'il ne se bloque pas, vous ne pouvez donc pas utiliser la fonctionnalité de contrôle de lancement KeepAlive. En outre, cela ne semble pas fonctionner pour le but souhaité. Si quelqu'un connaît un moyen d'exécuter adb en mode "démon", il ne revient donc pas, alors ce mécanisme launchctl pourrait être configuré pour le redémarrer automatiquement s'il meurt, garantissant ainsi que Jenkins ne deviendra jamais propriétaire. Eh bien, pour le moment, je vais simplement exécuter "adb devices" dans une fenêtre shell et la laisser ouverte.


1

J'ai résolu ce problème en utilisant une multiprise programmable pour redémarrer les concentrateurs USB avant chaque test. Cela a fait la même chose que de débrancher et de rebrancher les câbles USB.


Pouvez-vous développer davantage?
Dinesh

1

Je voulais juste donner suite à l'excellente suggestion de juan-delgado . J'ai trouvé sur MacOS High Sierra que l'exécution adbtoutes les 10 secondes avec la watchcommande était également efficace comme solution rapide:

watch -n 10 adb -d devices

Cela me permet de contourner la création d'un .plistfichier, mais l'inconvénient évident est que ce n'est pas une solution permanente. La watchcommande est disponible sur les versions précédentes d'OSX, elle devrait donc également être efficace.


Je n'avais pas watchsur macOS Catalina, mais j'ai pu l'installer facilement avec brew install watch.
mokagio Il y a

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.