Umgehen des ADB-Problems „Warten auf Gerät“

9

Wir richten einen kontinuierlichen Integrationsserver für unsere Android-Entwicklung ein und stoßen schnell darauf, dass ADB auf Geräteprobleme wartet .

Für die Aufzeichnung haben wir eine Menge von Kombinationen von bereits versucht adb kill-server, adb start-server, adb devicesusw. ohne Erfolg.

Leider habe ich im Internet nur Variationen von "Gerät ausstecken und wieder einstecken" gefunden, was für uns offensichtlich keine Lösung ist (wir können es uns nicht ersparen, dass ein Mensch am CI-Server sitzt, um Geräte aus- und wieder einzustecken) jeder Build).

Als Hintergrund verwenden wir Jenkins auf einem Mac, da dort auch unser CI für iOS ausgeführt wird.

Als ich mich dem Problem näherte, dachte ich, wenn das Gerät auf Betriebssystemebene gefunden wird, ist das zumindest ein Anfang. Wenn Sie einen Befehl wie system_profiler SPUSBDataTypeerfolgreich ausführen, wird das Gerät gefunden, einschließlich der Seriennummer, die ADB bei ordnungsgemäßer Arbeit meldet.

Ich habe ein paar ziemlich lahme Befehle versucht, um alle USB-Aktivitäten zu "aktualisieren", aber ich bin nirgendwo hingegangen. Es ist nicht so, dass Sie das Gerät ein- oder aushängen können, aber um ehrlich zu sein, bin ich mir nicht einmal sicher, wo das Problem liegt. Ich weiß nicht genug über USB-Protokolle auf niedriger Ebene, geschweige denn für Macs. Mein Lauern des ADB-Quellcodes war sehr, sehr langwierig.

An diesem Punkt bin ich gespannt auf eine Lösung, mit der wir Android auf unserem CI-Server konsistent ausführen können. Sei es ein paar Befehle vor jedem Jenkins-Job, das Patchen von ADB oder einem anderen schwarzen Zaubertrick.

Juan Delgado
quelle

Antworten:

9

Ich habe einen Weg gefunden, das Problem zu lösen. Der Vollständigkeit halber hier posten. Bitte beachten Sie, dass ich nicht sage, dass dies der beste Weg ist, es zu lösen, aber es hat bei uns funktioniert.

Wir stellten fest, dass das Problem nach langen Perioden der CI-Inaktivität (im Bereich von Stunden) auftrat. Deshalb haben wir ein einfaches Skript erstellt, das adb devicesalle 10 Sekunden aufgerufen wird. Und das Problem ist weg, keine Probleme mehr beim Warten auf das Gerät.

Unter Linux können Sie dies mit einem einfachen cronJob und unter OSX mit tun, launchctlund ich bin sicher, dass es ein Windows-Äquivalent gibt.

Unabhängig davon löste das "Pingen" der Geräte alle 10 Sekunden das Problem für uns.

Juan Delgado
quelle
1
Vielen Dank! Scheint, als hätte ich das gleiche Problem. Durch Abziehen und Zurückstecken des USB-Kabels wurde das Gerät in der Liste angezeigt.
Jorge Pedret
5

Das Aktivieren des USB-Debugging (Einstellungen => Entwickleroptionen) im Telefon hat geholfen.

ich verehre
quelle
1

Wir hatten einige ähnliche Probleme mit unserer Continuous Integration-Umgebung mit Android-Geräten von einem OSX-Computer (auch für iOS und Android).

Ich glaube, das Problem ist, dass Sie Jenkins erlauben, den ADB-Server zu starten. Dies verursacht Probleme, da Jenkins Jobs mit Muscheln verbunden sind, die ein- und ausgehen. Wenn Jenkins den ADB-Daemon beispielsweise mit einem Aufruf von "ADB Devices" startet, gehört der ADB-Daemon einer kurzlebigen Jenkins-Shell. Wenn diese Shell ausgeführt und geschlossen wird, wird der ADB-Daemon bereinigt , bis es automatisch durch einen anderen adb-Aufruf gesichert wird. Dies führt zu einem Zyklus des Startens und Stoppens des adb-Daemons. Sie möchten jedoch, dass er nur auf unbestimmte Zeit aktiv bleibt.

Eine Möglichkeit, dies zu beheben, besteht darin, "adb-Geräte" einfach über eine Shell auszuführen, die auf dem CI-Computer offen bleibt. Sie können erkennen, ob es sich um den übergeordneten Prozess handelt, indem Sie feststellen, ob diese Nachricht nach dem Ausführen angezeigt wird

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

Dies ist ein ärgerlicher Schritt, den Sie bei jedem Neustart Ihres Computers ausführen müssen. Wenn jemand dieses Befehlsfenster schließt, kehren Sie zum vorherigen Problem zurück.

Theoretisch wäre es besser, eine .plist-Datei zu erstellen, um den adb-Daemon beim Booten auszulösen. Hier ist ein Beispiel: ~ / Library / LaunchAgents / server.adb.plist. Dies führt im Grunde nur den adb start-server vom User Launch Daemon aus, um zu verhindern, dass Jenkins ihn besitzt.

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

Das Problem dabei ist jedoch, dass es nur adb startet, aber nicht blockiert, sodass Sie die KeepAlive-Startsteuerungsfunktion nicht verwenden können. Außerdem scheint es nicht für den gewünschten Zweck zu funktionieren. Wenn jemand eine Möglichkeit kennt, adb im "Daemon" -Modus auszuführen, damit es nicht zurückkehrt, kann dieser launchctl-Mechanismus so eingerichtet werden, dass es automatisch neu gestartet wird, wenn es stirbt, wodurch sichergestellt wird, dass Jenkins niemals Eigentümer wird. Na ja, jetzt werde ich nur "adb-Geräte" in einem Shell-Fenster ausführen und es offen lassen.

jpadams
quelle
1

Ich habe dieses Problem gelöst, indem ich vor jedem Testlauf eine programmierbare Steckdosenleiste verwendet habe, um die USB-Hubs neu zu starten. Dies geschah genauso wie das Herausziehen und Wiedereinstecken der USB-Kabel.

Justin Ison
quelle
Kannst du mehr ausstoßen?
Dinesh
0

Hier durch Wechseln des USB-Kabels gelöst

Anona112
quelle
Könnten Sie bitte detaillierter sein?
Donald Duck
0

Ich wollte nur dem ausgezeichneten Vorschlag von Juan-Delgado folgen . Unter MacOS High Sierra stellte ich fest, dass das Ausführen adballer 10 Sekunden mit dem watchBefehl auch als schnelle Problemumgehung wirksam war:

watch -n 10 adb -d devices

Dies ermöglicht es mir, das Erstellen einer .plistDatei zu umgehen , aber der offensichtliche Nachteil ist, dass es keine dauerhafte Lösung ist. Der watchBefehl ist in früheren Versionen von OSX verfügbar, so dass es auch dort wirksam sein sollte.

user43718
quelle