Como solucionar o problema de "aguardando dispositivo" do ADB

9

Estamos configurando um servidor de integração contínua para o nosso desenvolvimento Android e encontramos rapidamente o ADB aguardando um problema no dispositivo .

Para o registro, nós já tentamos um monte de combinações de adb kill-server, adb start-server, adb devices, etc. sem sucesso.

Infelizmente, tudo o que encontrei na internet são variações de "desconecte e reconecte o dispositivo", o que obviamente não é uma solução para nós (não podemos poupar que um ser humano se sente no servidor de CI para desconectar e reconectar dispositivos antes cada compilação).

Como pano de fundo, usamos o Jenkins em um Mac, pois ele também executa nosso IC para iOS.

Ao abordar o problema, pensei que, se no nível do sistema operacional, o dispositivo for encontrado, isso é pelo menos um começo. De fato, a execução de um comando como o system_profiler SPUSBDataTypeencontra com êxito o dispositivo, incluindo o número de série que o ADB relata ao funcionar corretamente.

Eu tentei alguns comandos bastante coxos para "atualizar" todas as atividades do USB, mas não fui a lugar algum. Não é que você possa montar / desmontar o dispositivo, mas, para ser sincero, nem sei ao certo onde está o problema, não sei o suficiente sobre protocolos USB de baixo nível, muito menos para Macs. Meu espreitar o código-fonte do ADB foi um tiro muito, muito longo.

Então, neste momento, sou totalmente a favor de uma solução que nos permita executar o Android de forma consistente no nosso servidor de IC. Seja alguns comandos antes de cada trabalho de Jenkins, remendando o ADB ou qualquer outro truque de magia negra.

Juan Delgado
fonte

Respostas:

9

Encontrei uma maneira de resolvê-lo, portanto, publique aqui para garantir a integridade. Observe que não estou dizendo que essa é a melhor maneira de resolvê-la, mas funcionou para nós.

Então, percebemos que o problema ocorreu após longos períodos de inatividade do IC (no intervalo de horas). Por isso, criamos um script simples que chama a adb devicescada 10 segundos. E o problema se foi, não há mais problemas de "espera pelo dispositivo".

No Linux, você pode fazer isso com um crontrabalho simples e no OSX com, launchctle tenho certeza que há um equivalente do Windows.

Independentemente disso, "executar ping" nos dispositivos a cada 10 segundos resolveu o problema para nós.

Juan Delgado
fonte
11
Obrigado! Parece que eu estava tendo o mesmo problema. Desconectar e reconectar o cabo USB fez o dispositivo aparecer na lista.
Jorge Pedret
5

A ativação da depuração USB (Configurações => Opções do desenvolvedor) no telefone ajudou.

eu adoro
fonte
1

Tivemos alguns problemas semelhantes com nosso ambiente de integração contínua com dispositivos Android de uma máquina OSX (também usando para iOS e Android).

Acredito que o problema é que você está permitindo que o Jenkins inicie o servidor adb. Os problemas causam porque os trabalhos de Jenkins estão associados a conchas que entram e saem da existência. Se o Jenkins iniciar o daemon adb com uma chamada de "dispositivos adb" (por exemplo), o daemon adb será de propriedade de algum shell Jenkins de vida curta e, quando esse shell terminar de executar e fechar, o daemon adb será limpo , até que o backup seja iniciado automaticamente por outra chamada adb. Isso resulta em um ciclo de iniciar e parar o daemon adb, mas o que você deseja é que ele permaneça indefinidamente.

Uma maneira de corrigir isso é apenas executar "adb devices" a partir de um shell que fica aberto na máquina de CI. Você pode saber se é o processo pai se esta mensagem é mostrada após a execução

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

Esta é uma etapa irritante que você deve executar sempre que a máquina reiniciar e, se alguém fechar a janela de comando, você voltará ao problema anterior.

Em teoria, uma maneira melhor seria criar um arquivo .plist para acionar o daemon adb na inicialização. Aqui está um exemplo: ~ / Library / LaunchAgents / server.adb.plist. Isso basicamente executa o servidor de inicialização adb no daemon de inicialização do usuário para evitar que Jenkins o possua.

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

O problema com isso, no entanto, é que ele apenas inicia o adb, mas não é bloqueado, portanto você não pode usar a funcionalidade de controle de inicialização do KeepAlive. Além disso, parece não funcionar para a finalidade desejada. Se alguém souber uma maneira de executar o adb no modo "daemon", para que ele não retorne, esse mecanismo launchctl poderá ser configurado para reiniciá-lo automaticamente se ele morrer, garantindo assim que o Jenkins nunca obtenha a propriedade. Oh, bem, por enquanto eu vou apenas rodar "adb devices" em uma janela de shell e deixá-la aberta.

jpadams
fonte
1

Resolvi isso usando uma régua de energia programável para reiniciar os hubs usb antes de cada teste. Isso fez o mesmo que desconectar e conectar os cabos USB novamente.

Justin Ison
fonte
Você pode expalin mais?
Dinesh
1

Eu só queria acompanhar a excelente sugestão de juan-delgado . Eu descobri no MacOS High Sierra que executar a adbcada 10 segundos com o watchcomando também era eficaz como uma solução rápida:

watch -n 10 adb -d devices

Isso me permite evitar a criação de um .plistarquivo, mas a desvantagem óbvia é que não é uma solução permanente. O watchcomando está disponível nas versões anteriores do OSX, portanto deve ser eficaz também.

user43718
fonte
Eu não tinha watchno macOS Catalina, mas consegui instalá-lo facilmente brew install watch.
mokagio
0

Resolvido aqui alterando o cabo USB

Anona112
fonte
Poderia, por favor, ser mais detalhado?
Donald Duck