Obejście problemu ADB „oczekiwanie na urządzenie”


9

Tworzymy serwer ciągłej integracji dla naszego rozwoju Androida i szybko natknęliśmy się na ADB czekające na problem z urządzeniem .

Dla przypomnienia, już próbowałem wiele kombinacji adb kill-server, adb start-server, adb devicesitp bezskutecznie.

Niestety, wszystko, co znalazłem w Internecie, to odmiany „odłącz i ponownie podłącz urządzenie”, co oczywiście nie jest dla nas rozwiązaniem (nie możemy oszczędzić człowiekowi usiąść przy serwerze CI, aby odłączyć i ponownie podłączyć urządzenia przed każda kompilacja).

Jako trochę tła używamy Jenkinsa na komputerze Mac, ponieważ obsługuje on również nasz CI dla iOS.

Zbliżając się do problemu, pomyślałem, że jeśli na poziomie systemu operacyjnego urządzenie zostanie znalezione, to przynajmniej początek. Rzeczywiście, uruchomienie polecenia takiego jak system_profiler SPUSBDataTypepomyślne wyszukuje urządzenie, w tym numer seryjny zgłoszony przez ADB przy prawidłowej pracy.

Próbowałem kilka raczej kiepskich poleceń, aby „odświeżyć” całą aktywność USB, ale nigdzie nie poszedłem. Nie chodzi o to, że możesz zamontować / odmontować urządzenie, ale szczerze mówiąc, nie jestem nawet pewien, gdzie jest problem, nie wiem wystarczająco dużo o protokołach USB niskiego poziomu, nie mówiąc już o komputerach Mac. Moje przeczucie kodu źródłowego ADB było bardzo, bardzo dalekie.

Więc w tym momencie jestem gotów na rozwiązanie, które pozwoliłoby nam konsekwentnie uruchamiać Androida na naszym serwerze CI. Czy to kilka poleceń przed każdym zadaniem Jenkinsa, załatanie ADB lub innej sztuczki czarnej magii.

Odpowiedzi:


9

Znalazłem sposób na jego rozwiązanie, więc opublikuj tutaj, aby uzyskać kompletność. Pamiętaj, że nie mówię, że jest to najlepszy sposób na rozwiązanie tego problemu, ale zadziałał dla nas.

Uświadomiliśmy sobie, że problem pojawił się po długich okresach bezczynności CI (w zakresie godzin). Stworzyliśmy więc prosty skrypt, który wywołuje adb devicesco 10 sekund. Problem zniknął, nie ma już problemów z „czekaniem na urządzenie”.

W systemie Linux możesz to zrobić za pomocą prostej cronpracy, a w systemie OSX za launchctli jestem pewien, że istnieje odpowiednik systemu Windows.

Niezależnie od tego, „pingowanie” urządzeń co 10 sekund rozwiązało to dla nas.


1
Dzięki! Wygląda na to, że miałem ten sam problem. Odłączenie i ponowne podłączenie kabla USB spowodowało, że urządzenie pojawi się na liście.
Jorge Pedret

5

Pomogło włączenie debugowania USB (Ustawienia => Opcje programisty) w telefonie.


1

Mieliśmy podobne problemy z naszym środowiskiem Continuous Integration z urządzeniami z Androidem z komputera z systemem OSX (również używanym na iOS i Android).

Uważam, że problem polega na tym, że pozwalasz Jenkinsowi uruchomić serwer adb. Powoduje problemy, ponieważ zadania Jenkins są powiązane z powłokami, które wchodzą i znikają. Jeśli Jenkins uruchomi demona adb za pomocą wywołania „urządzenia adb” (na przykład), wówczas demon adb będzie własnością krótkotrwałej powłoki Jenkins, a kiedy ta powłoka skończy się uruchamiać i zamykać, demon adb zostanie wyczyszczony , dopóki nie zostanie uruchomione automatycznie przez kolejne wywołanie adb. Powoduje to cykl uruchamiania i zatrzymywania demona adb, ale to, czego chcesz, to pozostanie bez końca.

Jednym ze sposobów, aby to naprawić, jest po prostu uruchomienie „urządzeń adb” z powłoki, która pozostaje otwarta na komputerze CI. Możesz stwierdzić, czy jest to proces nadrzędny, czy ten komunikat jest wyświetlany po uruchomieniu

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

Jest to irytujący krok, który należy wykonać przy każdym ponownym uruchomieniu komputera, a jeśli ktoś zamknie to okno poleceń, powrócisz do poprzedniego problemu.

Teoretycznie lepszym sposobem byłoby utworzenie pliku .plist w celu uruchomienia demona adb podczas uruchamiania. Oto przykład: ~ / Library / LaunchAgents / server.adb.plist. To po prostu uruchamia serwer startowy adb z demona uruchamiania użytkownika, aby uniknąć posiadania go przez Jenkinsa.

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

Problem polega jednak na tym, że po prostu zaczyna adb, ale nie blokuje, więc nie można korzystać z funkcji kontroli uruchamiania KeepAlive. Ponadto nie wydaje się, aby działał w pożądanym celu. Jeśli ktoś wie, jak uruchomić adb w trybie „demona”, aby nie powrócił, to można ustawić ten mechanizm uruchamiania tak, aby automatycznie uruchamiał go ponownie, jeśli umrze, zapewniając w ten sposób, że Jenkins nigdy nie przejmie własności. No cóż, na razie będę po prostu uruchamiał „urządzenia adb” w oknie powłoki i pozostawiłem otwarte.


1

Rozwiązałem to za pomocą programowalnej listwy zasilającej, aby ponownie uruchomić koncentratory USB przed każdym uruchomieniem testowym. To samo zrobiło się z odłączeniem i ponownym podłączeniem kabli USB.


Czy możesz wyjaśnić więcej?
Dinesh

1

Chciałem tylko skorzystać z doskonałej sugestii Juana-Delgado . W MacOS High Sierra odkryłem, że uruchamianie adbco 10 sekund z watchpoleceniem było również skuteczne jako szybkie obejście:

watch -n 10 adb -d devices

Pozwala mi to uniknąć tworzenia .plistpliku, ale oczywistą wadą jest to, że nie jest to trwałe rozwiązanie. watchPolecenie jest dostępne w poprzednich wersjach systemu OSX, więc powinno być skuteczne również tam.


Nie miałem watchna macOS Catalina, ale mogłem go łatwo zainstalować brew install watch.
mokagio

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.