Trabalhando com o problema do ADB “waiting for device”

9

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

Para o registro, já tentamos muitas 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 "desconectar e reconectar o dispositivo", o que obviamente não é uma solução para nós (não podemos evitar que um ser humano fique sentado no servidor de CI para desconectar e desconectar dispositivos de replicação antes de cada compilação).

Como pano de fundo, usamos o Jenkins em um Mac, já que ele também executa o CI para iOS.

Ao abordar o problema, pensei que, no nível do sistema operacional, o dispositivo é encontrado, pelo menos é um começo. Na verdade, executar um comando como system_profiler SPUSBDataType com êxito localiza o dispositivo, incluindo o número de série que o ADB relata ao funcionar corretamente.

Eu tentei alguns comandos bem ruins para "atualizar" toda a atividade do USB, mas não fui a lugar nenhum. Não é que você possa montar / desmontar o dispositivo, mas, para ser honesto, não sei ao certo onde está o problema, não sei o suficiente sobre protocolos USB de baixo nível, muito menos para Macs. Minha ocultação do código fonte do ADB foi muito, muito longa.

Portanto, neste ponto, estou atento a uma solução que nos permita executar consistentemente o Android em nosso servidor de CI. Seja alguns comandos antes de cada trabalho de Jenkins, remendando o ADB ou qualquer outro truque de magia negra.

    
por Juan Delgado 10.01.2014 / 17:35

6 respostas

9

Encontrou uma maneira de resolvê-lo, então postar aqui para ser completo. Por favor, note que eu não estou dizendo que esta é a melhor maneira de resolvê-lo, mas funcionou para nós.

Então, percebemos que o problema aconteceu após longos períodos de inatividade do IC (no intervalo de horas). Então, criamos um script simples que chama adb devices a cada 10 segundos. E o problema desapareceu, não há mais problemas com "espera por dispositivo".

No Linux, você pode fazer isso com um simples trabalho cron e no OSX com launchctl e tenho certeza de que há um equivalente do Windows.

Independentemente disso, o "ping" dos dispositivos a cada 10 segundos resolveu isso para nós.

    
por 20.01.2014 / 11:24
5

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

    
por 11.07.2014 / 10:47
1

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

Eu acredito que o problema é que você está permitindo que Jenkins inicie o servidor adb. Isso causa problemas porque os trabalhos de Jenkins estão associados a shells que entram e saem da existência. Se Jenkins iniciar o adb daemon com uma chamada "adb devices" (por exemplo), o adb daemon será de propriedade de alguns shell Jenkins de curta duração, e quando esse shell terminar de executar e fechar, o adb daemon será limpo , até que seja iniciado automaticamente por outra chamada de adb. Isso resulta em um ciclo de iniciar e parar o daemon adb, mas o que você quer é que ele permaneça indefinidamente.

Uma forma de corrigir isso é simplesmente executar "dispositivos adb" a partir de um shell que fica aberto na máquina do CI. Você pode dizer 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

Este é um passo chato de ter que executar toda vez que sua máquina reinicia, 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 apenas executa adb start-server a partir do daemon de ativaçã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 começa a adb, mas ele não bloqueia, então você não pode usar a funcionalidade de controle de lançamento KeepAlive. Além disso, não parece funcionar para o propósito desejado. Se alguém souber de 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, portanto, que o Jenkins nunca seja o proprietário. Ah, bem, por enquanto eu só vou estar executando "dispositivos adb" em uma janela do shell e deixando-o aberto.

    
por 16.02.2015 / 23:27
0

Eu resolvi isso usando uma régua de energia programável para reinicializar os hubs usb antes de cada execução de teste. Isso fez o mesmo que desconectar e conectar os cabos USB novamente.

    
por 28.10.2015 / 16:43
0

Resolvido aqui alterando o cabo USB

    
por 18.09.2017 / 20:22
0

Eu só queria seguir a excelente sugestão de juan-delgado . Eu encontrei no MacOS High Sierra que executar adb a cada 10 segundos com o comando watch também foi eficaz como uma solução rápida:

watch -n 10 adb -d devices

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

    
por 12.06.2018 / 19:45