Работа вокруг проблемы «ожидания устройства» АБР

9

Мы настраиваем сервер непрерывной интеграции для нашей разработки под Android, и мы быстро столкнулись с ожиданием проблем с устройством в АБР .

Для записи, мы уже пробовали много комбинаций adb kill-server, adb start-server, adb devicesи т.д., но безрезультатно.

К сожалению, все, что я нашел в интернете, это варианты «отключить и снова подключить устройство», что, очевидно, не является для нас решением (мы не можем позволить человеку сидеть рядом с CI-сервером, чтобы отключить и снова подключить устройства перед каждая сборка).

В качестве предыстории мы используем Jenkins на Mac, поскольку он также запускает наш CI для iOS.

Подходя к проблеме, я подумал, что если на уровне ОС устройство найдено, то это как минимум начало. Действительно, выполнение команды like system_profiler SPUSBDataTypeуспешно находит устройство, включая серийный номер, который ADB сообщает при правильной работе.

Я попытался выполнить несколько довольно слабых команд, чтобы «обновить» всю активность USB, но я никуда не попал. Дело не в том, что вы можете монтировать / размонтировать устройство, но, честно говоря, я даже не уверен, в чем проблема, я недостаточно знаю о низкоуровневых USB-протоколах, не говоря уже о Mac. Мое скрытие исходного кода АБР было очень, очень длинным выстрелом.

Так что на данный момент я полностью заинтересован в решении, которое позволило бы нам постоянно запускать Android на нашем CI-сервере. Будь то несколько команд перед каждой работой Дженкинса, исправление ADB или любой другой фокус черной магии.

Хуан Дельгадо
источник

Ответы:

9

Нашел способ ее решения, поэтому выкладываю сюда для полноты. Обратите внимание, что я не говорю, что это лучший способ решить эту проблему, но он работает для нас.

Итак, мы поняли, что проблема возникла после длительных периодов бездействия КИ (в диапазоне часов). Поэтому мы создали простой скрипт, который вызывает adb devicesкаждые 10 секунд. И проблема исчезла, больше нет проблем с «ожиданием устройства».

В Linux вы можете сделать это с помощью простой cronработы, а в OSX - launchctlи я уверен, что есть эквивалент Windows.

Несмотря на это, «пинг» устройств каждые 10 секунд решил для нас.

Хуан Дельгадо
источник
1
Спасибо! Похоже, у меня была та же проблема. Отключение и подключение USB-кабеля заставило устройство появиться в списке.
Хорхе Педрет
5

Помогло включение отладки по USB (Настройки => Параметры разработчика) в телефоне.

я обожаю
источник
1

У нас были некоторые похожие проблемы с нашей средой непрерывной интеграции с устройствами Android с машины OSX (также используемой как для iOS, так и для Android).

Я считаю, что проблема в том, что вы разрешаете Дженкинсу запускать сервер adb. Причины проблемы, потому что рабочие места Jenkins связаны с оболочками, которые входят и выходят из существования. Если Jenkins запускает демон adb с помощью вызова «adb devices» (например), тогда демон adb будет принадлежать какой-то недолгой оболочке Jenkins, и когда эта оболочка завершит работу и закроется, демон adb будет очищен До тех пор, пока он не будет запущен автоматически другим вызовом ADB. Это приводит к циклу запуска и остановки демона adb, но вы хотите, чтобы он просто оставался на неопределенное время.

Один из способов исправить это - просто запустить «adb devices» из оболочки, которая остается открытой на машине CI. Вы можете сказать, является ли это родительским процессом, по тому, отображается ли это сообщение после запуска

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

Это раздражающий шаг, который приходится выполнять каждый раз, когда ваша машина перезагружается, и если кто-то закроет это командное окно, вы вернетесь к предыдущей проблеме.

Теоретически, лучшим способом было бы создать файл .plist для запуска демона adb при загрузке. Вот пример: ~ / Library / LaunchAgents / server.adb.plist. Это в основном просто запускает adb start-server из демона запуска пользователя, чтобы избежать владения им у Jenkins.

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

Проблема с этим, однако, в том, что он просто запускает adb, но не блокирует, так что вы не можете использовать функцию контроля запуска KeepAlive. Кроме того, это, кажется, не работает для желаемой цели. Если кто-нибудь знает способ запуска adb в режиме «daemon», чтобы он не возвращался, то этот механизм launchctl может быть настроен на автоматический перезапуск, если он умрет, что гарантирует, что Jenkins никогда не получит право собственности. Ну что ж, сейчас я буду просто запускать "adb devices" в окне оболочки и оставлять его открытым.

jpadams
источник
1

Я решил эту проблему, используя программируемый удлинитель для перезагрузки USB-концентраторов перед каждым тестом. Это было то же самое, что отключить и снова подключить USB-кабели.

Джастин изон
источник
Можете ли вы объяснить больше?
Динеш
1

Я просто хотел последовать прекрасному предложению Хуан-Дельгадо . Я обнаружил на MacOS High Sierra, что запуск adbкаждые 10 секунд с watchкомандой также был эффективным быстрым решением:

watch -n 10 adb -d devices

Это позволяет мне обойтись без создания .plistфайла, но очевидным недостатком является то, что это не постоянное решение. Команда watchдоступна в предыдущих версиях OSX, поэтому она должна быть эффективной и там.

user43718
источник
У меня не было watchMacOS Catalina, но я смог легко установить его brew install watch.
мокагио
0

Решается здесь, меняя USB-кабель

Anona112
источник
Не могли бы вы быть более подробным?
Дональд Дак