Risolvere il problema di "attesa del dispositivo" ADB


9

Stiamo configurando un server di integrazione continua per il nostro sviluppo Android e ci siamo imbattuti rapidamente nell'attesa di ADB per il problema dei dispositivi .

Per la cronaca, abbiamo già provato molte combinazioni di adb kill-server, adb start-server, adb devices, ecc senza alcun risultato.

Purtroppo, tutto quello che ho trovato su Internet sono le varianti di "scollegare e ricollegare il dispositivo", che ovviamente non è una soluzione per noi (non possiamo risparmiare un essere umano seduto sul server CI per scollegare e ricollegare i dispositivi prima ogni build).

Come sfondo, utilizziamo Jenkins su un Mac, poiché esegue anche il nostro CI per iOS.

Mentre mi avvicinavo al problema, ho pensato che se a livello di sistema operativo si trova il dispositivo, questo è almeno un inizio. In effetti, l'esecuzione di un comando come system_profiler SPUSBDataTypetrova correttamente il dispositivo, incluso il numero seriale riportato da ADB quando funziona correttamente.

Ho provato alcuni comandi piuttosto scadenti per "aggiornare" tutte le attività USB, ma non sono andato da nessuna parte. Non è che puoi montare / smontare il dispositivo, ma a dire il vero non sono nemmeno sicuro di dove sia il problema, non so abbastanza sui protocolli USB di basso livello, figuriamoci per i Mac. Il mio agguato al codice sorgente ADB è stato un colpo molto, molto lungo.

Quindi a questo punto sono pronto per una soluzione che ci consenta di eseguire costantemente Android sul nostro server CI. Sia qualche comando prima di ogni lavoro Jenkins, patch ADB o qualsiasi altro trucco di magia nera.

Risposte:


9

Ho trovato un modo per risolverlo, quindi pubblicando qui per completezza. Si noti che non sto dicendo che questo è il modo migliore per risolverlo, ma ha funzionato per noi.

Quindi, ci siamo resi conto che il problema si verificava dopo lunghi periodi di inattività dell'IC (nel giro di ore). Quindi abbiamo creato un semplice script che chiama adb devicesogni 10 secondi. E il problema è sparito, non più problemi di "attesa del dispositivo".

Su Linux puoi farlo con un semplice cronlavoro e su OSX con launchctle sono sicuro che ci sia un equivalente di Windows.

Indipendentemente da ciò, il "ping" dei dispositivi ogni 10 secondi lo ha risolto per noi.


1
Grazie! Sembra che avessi lo stesso problema. Scollegare e ricollegare il cavo USB ha fatto apparire il dispositivo nell'elenco.
Jorge Pedret,

5

Abilitazione del debug USB (Impostazioni => Opzioni sviluppatore) nel telefono ha aiutato.


1

Abbiamo avuto alcuni problemi simili con il nostro ambiente di integrazione continua con dispositivi Android da una macchina OSX (anche per iOS e Android).

Credo che il problema sia che stai permettendo a Jenkins di avviare il server adb. Ciò causa problemi perché i lavori di Jenkins sono associati a conchiglie che entrano ed escono. Se Jenkins dà il via al demone adb con una chiamata "dispositivi adb" (ad esempio), il demone adb sarà di proprietà di una shell Jenkins di breve durata e quando quella shell termina l'esecuzione e si chiude, il demone adb verrà ripulito , fino a quando non viene avviato automaticamente il backup da un'altra chiamata adb. Ciò si traduce in un ciclo di avvio e arresto del demone adb, ma ciò che si desidera è che rimanga sveglio all'infinito.

Un modo per risolvere questo problema è semplicemente eseguire "dispositivi adb" da una shell che viene lasciata aperta sul computer CI. Puoi stabilire se si tratta del processo principale se questo messaggio viene visualizzato dopo l'esecuzione

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

Questo è un passaggio fastidioso da eseguire ogni volta che la macchina si riavvia e se qualcuno chiude quella finestra di comando tornerai al problema precedente.

In teoria, un modo migliore sarebbe quello di creare un file .plist per attivare il demone adb all'avvio. Ecco un esempio: ~ / Library / LaunchAgents / server.adb.plist. Questo in pratica esegue adb start-server dal demone di avvio dell'utente per evitare che Jenkins lo possieda.

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

Il problema con questo, tuttavia, è che inizia solo adb, ma non si blocca, quindi non è possibile utilizzare la funzionalità di controllo di avvio KeepAlive. Inoltre, non sembra funzionare per lo scopo desiderato. Se qualcuno conosce un modo per eseguire adb in modalità "daemon", quindi non ritorna, allora questo meccanismo launchctl potrebbe essere impostato per riavviarlo automaticamente se muore, assicurando quindi che Jenkins non ottenga mai la proprietà. Oh bene, per ora eseguirò "dispositivi adb" in una finestra shell e lasciandolo aperto.


1

Ho risolto questo problema utilizzando una ciabatta programmabile per riavviare gli hub USB prima di ogni test. Ciò ha fatto lo stesso di scollegare e ricollegare i cavi USB.


Puoi espirare di più?
Dinesh,

1

Volevo solo dare seguito all'eccellente suggerimento di Juan-delgado . Ho scoperto su MacOS High Sierra che eseguire adbogni 10 secondi con il watchcomando era efficace anche come soluzione rapida:

watch -n 10 adb -d devices

Questo mi permette di eludere la creazione di un .plistfile, ma l'ovvio svantaggio è che non è una soluzione permanente. Il watchcomando è disponibile nelle versioni precedenti di OSX, quindi dovrebbe essere efficace anche lì.


Non avevo watchsu macOS Catalina, ma sono stato in grado di installarlo facilmente con brew install watch.
mokagio il

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.