ADB
Шпаргалка по adb для отладки и прогона автотестов. Везде, где есть <pkg>, подставляется имя пакета, например com.example.app.
#Подключение и устройства
Если устройств больше одного, любая команда требует -s <serial>, иначе adb ругнётся more than one device.
adb devices -l
Список устройств с моделью, транспортом и device-id. unauthorized — не принят RSA-ключ на устройстве, offline — висит транспорт.
adb -s emulator-5554 shell
adb -d shell # единственное USB-устройство
adb -e shell # единственный эмулятор
Выбор цели. -d и -e удобнее, когда подключены ровно одно устройство и один эмулятор.
adb kill-server && adb start-server
Первое, что стоит сделать при offline, залипшем списке устройств или после смены USB-порта.
adb wait-for-device shell getprop sys.boot_completed
Блокируется до появления устройства. В CI полезнее дождаться именно sys.boot_completed=1, а не просто транспорта.
Готовность эмулятора: adb wait-for-device shell 'while [ "$(getprop sys.boot_completed)" != 1 ]; do sleep 1; done'
adb pair 192.168.1.50:37891 # код из «Отладка по Wi-Fi»
adb connect 192.168.1.50:5555
Wireless debugging начиная с Android 11: сначала одноразовое спаривание с PIN-кодом, затем подключение. Порты у пары и подключения разные, оба показаны в настройках.
adb tcpip 5555
adb connect 192.168.1.50:5555
adb usb # вернуться на USB
Старый путь через USB: переключить демон на TCP, затем отсоединить кабель. Работает и на Android 10 и ниже.
adb disconnect # все сетевые
adb disconnect 192.168.1.50:5555
Отключение сетевых транспортов. USB не затрагивает.
adb root
adb unroot
adb remount
Работает только на userdebug/eng-сборках и эмуляторах без Google Play. remount делает /system записываемым.
adb reboot
adb reboot bootloader
adb reboot recovery
Перезагрузка в нужный режим.
#Информация об устройстве
adb shell getprop ro.build.version.release # версия Android
adb shell getprop ro.build.version.sdk # API level
adb shell getprop ro.product.model
adb shell getprop ro.product.cpu.abi # arm64-v8a и т.п.
Точечное чтение свойств. Без аргумента getprop вывалит весь список — удобно грепать.
adb shell wm size
adb shell wm density
adb shell wm size 1080x1920 # переопределить
adb shell wm size reset
Разрешение и плотность. Переопределение полезно, чтобы воспроизвести баг вёрстки на «чужом» экране.
adb shell dumpsys battery
adb shell dumpsys battery set level 15
adb shell dumpsys battery unplug
adb shell dumpsys battery reset
Подмена состояния батареи — единственный вменяемый способ протестировать поведение при низком заряде.
adb shell settings get global auto_time
adb shell settings put system accelerometer_rotation 0
adb shell settings list global
Пространства: global, system, secure. Часть значений требует WRITE_SECURE_SETTINGS и не пишется на release-сборке.
adb shell date
adb shell getprop persist.sys.timezone
Время и таймзона устройства. Расхождение с сервером — классическая причина падений тестов на токенах и подписях.
#Пакеты и приложения
adb install app.apk
adb install -r app.apk # переустановить, данные сохранить
adb install -g app.apk # выдать все runtime-разрешения
adb install -t app.apk # разрешить test-only сборку
adb install -d app.apk # разрешить downgrade
-g — то, что нужно почти всегда в автотестах: снимает диалоги разрешений на старте.
adb install-multiple base.apk split_config.arm64_v8a.apk split_config.ru.apk
Установка split-APK. Из .aab набор сплитов получается через bundletool.
adb uninstall <pkg>
adb uninstall -k <pkg> # снести, но оставить данные и кеш
Удаление. -k оставляет каталог данных.
adb shell pm list packages -3 # только сторонние
adb shell pm list packages -s # только системные
adb shell pm list packages -d # отключённые
adb shell pm list packages -f <pkg> # с путём к apk
adb shell pm list packages | grep -i example
Поиск пакета, когда точное имя неизвестно.
adb shell pm path <pkg>
Пути к установленным apk. Дальше можно вытащить боевую сборку с устройства через adb pull.
adb shell pm clear <pkg>
Полный сброс: данные, кеш, разрешения, аккаунты. Самый надёжный способ привести приложение к состоянию «первый запуск» между тестами.
Дешевле и стабильнее, чем переустановка: не требует apk и не ломает подпись.
adb shell pm disable-user --user 0 <pkg>
adb shell pm enable <pkg>
adb shell pm hide <pkg>
Отключить приложение, не удаляя. Годится, чтобы убрать мешающий системный компонент на время прогона.
adb shell dumpsys package <pkg>
Всё про пакет: версия, подпись, разрешения (и запрошенные, и выданные), activity, receiver'ы, флаги установки.
adb shell dumpsys package <pkg> | grep -A2 versionName
Быстрая проверка, какая версия реально стоит на устройстве.
#Запуск, activity и deep links
adb shell am start -n <pkg>/.MainActivity
adb shell am start -n <pkg>/<pkg>.ui.MainActivity
Явный запуск. Точка в начале — сокращение до applicationId, но при разных applicationId и package нужно полное имя класса.
adb shell monkey -p <pkg> -c android.intent.category.LAUNCHER 1
Запуск «как из лаунчера», когда имя activity неизвестно.
adb shell am start -W -a android.intent.action.VIEW -d "myapp://profile/42" <pkg>
Проверка deep link. -W ждёт запуска и печатает TotalTime — удобная метрика холодного старта.
Ссылки с & обязательно в кавычках, иначе shell порежет на части.
adb shell am start -a android.intent.action.VIEW -d "https://example.com/x"
App Links. Если открылся браузер, а не приложение — смотри верификацию: adb shell pm get-app-links <pkg>.
adb shell am start -n <pkg>/.MainActivity --es key value --ei num 42 --ez flag true
Передача extras: --es строка, --ei int, --ez boolean, --el long, --ef float.
adb shell am force-stop <pkg>
adb shell am kill <pkg>
force-stop гарантированно валит процесс и сбрасывает стек activity. kill мягче — только если процесс в фоне.
adb shell am broadcast -a com.example.ACTION --es payload test
Отправка broadcast. Учти ограничения на неявные broadcast'ы начиная с Android 8.
adb shell dumpsys window | grep -E 'mCurrentFocus|mFocusedApp'
Что сейчас на экране. Самая частая команда при разборе «тест не находит элемент» — часто оказывается, что сверху чужой диалог.
adb shell dumpsys activity activities | grep -E 'ResumedActivity'
Текущая resumed-activity. Альтернатива предыдущей команде, стабильнее парсится.
adb shell am start-foreground-service -n <pkg>/.SyncService
adb shell am startservice -n <pkg>/.SyncService
Запуск сервиса напрямую.
#Логи
adb logcat
Поток целиком. Практически всегда нужен один из фильтров ниже.
adb logcat -c # очистить буфер
adb logcat -d # дампнуть и выйти
adb logcat -t 200 # последние 200 строк и выйти
Связка -c перед действием и -d после — базовый приём: в выводе только то, что относится к проверяемому шагу.
adb logcat --pid=$(adb shell pidof -s <pkg>)
Только логи своего приложения. Самый полезный фильтр: убирает системный шум целиком.
После force-stop или краша PID меняется — команду надо перезапустить.
adb logcat MyTag:D *:S
Только тег MyTag уровня Debug и выше, всё остальное заглушить. Уровни: V D I W E F S.
adb logcat -v threadtime
adb logcat -v time
adb logcat -v color
threadtime добавляет PID и TID — без него невозможно разбирать многопоточные гонки.
adb logcat -b crash
adb logcat -b events
adb logcat -b all
Отдельные буферы. crash — только падения, events — системные события (запуски activity, ANR, GC).
adb logcat -e 'HTTP [45][0-9][0-9]'
Фильтр по регулярке на стороне устройства. Дешевле, чем гонять весь поток через grep на хосте.
adb logcat -G 16M
Увеличить кольцевой буфер. Нужно, когда приложение логирует много, а падение случается редко.
adb logcat *:E > errors.log
Только ошибки в файл. На длинных прогонах — базовый артефакт.
adb shell setprop log.tag.OkHttp VERBOSE
Включить подробность конкретного тега без пересборки, если в коде используется Log.isLoggable.
adb bugreport bugreport.zip
Полный срез состояния системы: логи, dumpsys, ANR-трейсы. Тяжёлый, но незаменим при разборе ANR и утечек.
adb shell dumpsys dropbox --print | tail -100
adb shell ls /data/anr/
ANR-трейсы и системные крашдампы.
#Файлы, скриншоты, запись экрана
adb push local.txt /sdcard/Download/
adb pull /sdcard/Download/report.json ./
Обмен файлами. Каталог приложения /data/data/<pkg> напрямую недоступен без root.
adb shell run-as <pkg> ls -la /data/data/<pkg>/databases
adb shell run-as <pkg> cat /data/data/<pkg>/shared_prefs/prefs.xml
Доступ к приватным данным без root — работает для debuggable-сборок. Способ проверить, что реально записалось в prefs и БД.
adb exec-out run-as <pkg> cat /data/data/<pkg>/databases/app.db > app.db
Вытащить базу приложения на хост и открыть в любом SQLite-клиенте.
exec-out вместо shell — принципиально: shell портит бинарные данные заменой переводов строк.
adb exec-out screencap -p > screen.png
Скриншот прямо в файл на хосте, без промежуточного файла на устройстве.
adb shell screenrecord --time-limit 30 --bit-rate 4000000 /sdcard/rec.mp4
adb pull /sdcard/rec.mp4
Запись экрана, максимум 180 секунд. Звук не пишется.
adb shell screenrecord --size 720x1280 --output-format=h264 - > rec.h264
Стрим записи на хост без файла на устройстве.
adb shell ls -la /sdcard/
adb shell rm -r /sdcard/test-artifacts
adb shell mkdir -p /sdcard/test-artifacts
Обычные файловые операции внутри shell.
adb shell df -h /data
adb shell du -sh /data/data/<pkg>
Свободное место и размер данных приложения. Забитый /data — частая причина необъяснимых падений на длинных прогонах.
#Сеть и прокси
adb reverse tcp:8080 tcp:8080
Устройство видит localhost:8080 как порт 8080 на хосте. Так приложение подключается к локальному моку API без правки конфигов и без выяснения IP хоста.
Для автотестов это удобнее, чем прописывать IP: работает одинаково на эмуляторе и физическом устройстве.
adb forward tcp:9222 localabstract:chrome_devtools_remote
adb forward --list
adb forward --remove-all
Обратное направление: порт хоста проксируется на устройство. Пример — отладка WebView через Chrome DevTools.
adb shell settings put global http_proxy 10.0.2.2:8888
adb shell settings delete global http_proxy
Системный прокси — так трафик заворачивается в Charles или mitmproxy. 10.0.2.2 — хост со стороны эмулятора.
HTTPS без установленного CA будет отвергаться. Начиная с Android 7 приложение обязано явно доверять пользовательским CA через network_security_config.
adb shell ip addr show wlan0
adb shell ip route
adb shell ping -c 3 8.8.8.8
Диагностика сети с устройства.
adb shell svc wifi disable
adb shell svc wifi enable
adb shell svc data disable
Управление радио. Так тестируется поведение в offline без ковыряния в настройках руками.
adb shell cmd connectivity airplane-mode enable
adb shell cmd connectivity airplane-mode disable
Режим полёта. Надёжнее, чем гасить интерфейсы поодиночке.
adb shell dumpsys connectivity | head -40
adb shell dumpsys netstats | head -40
Состояние подключений и счётчики трафика по UID.
#Разрешения
adb shell pm grant <pkg> android.permission.CAMERA
adb shell pm revoke <pkg> android.permission.ACCESS_FINE_LOCATION
Выдача и отзыв runtime-разрешений. Только для тех, что объявлены в манифесте, иначе SecurityException.
adb shell pm reset-permissions
Сброс всех разрешений в исходное состояние. Полезно перед проверкой сценария первого запуска.
adb shell dumpsys package <pkg> | sed -n '/runtime permissions/,/^$/p'
Что реально выдано прямо сейчас.
adb shell appops set <pkg> RUN_IN_BACKGROUND deny
adb shell appops get <pkg>
App ops — более тонкий слой, чем разрешения: фоновая работа, доступ к уведомлениям, наложение поверх окон.
adb shell appops set <pkg> SYSTEM_ALERT_WINDOW allow
Наложение поверх других окон — без него часть инструментов автоматизации не работает.
#Ввод и дерево UI
adb shell input tap 540 1200
adb shell input swipe 540 1600 540 600 300 # последнее — длительность, мс
adb shell input text 'hello%sworld' # %s вместо пробела
adb shell input keyevent KEYCODE_BACK
Синтетический ввод. Координаты зависят от разрешения, так что для тестов это скорее отладочный инструмент, чем основа.
adb shell input keyevent 4 # BACK
adb shell input keyevent 3 # HOME
adb shell input keyevent 26 # POWER
adb shell input keyevent 82 # MENU
adb shell input keyevent 66 # ENTER
adb shell input keyevent 187 # APP_SWITCH (недавние)
Частые keycode. Полный список — в KeyEvent из Android SDK.
adb shell uiautomator dump /sdcard/ui.xml
adb pull /sdcard/ui.xml
# или одной командой:
adb exec-out uiautomator dump /dev/tty > ui.xml
Дамп дерева UI с resource-id, text, content-desc и границами. Основной способ понять, за что цепляться селектором.
adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0
Отключение анимаций. Убирает целый класс флаки-падений на ожиданиях и ускоряет прогон.
Обязательный шаг в подготовке устройства под автотесты. Сбрасывается значением 1.
adb shell settings put secure show_ime_with_hard_keyboard 0
adb shell ime list -s
adb shell ime disable com.google.android.inputmethod.latin
Экранная клавиатура умеет перекрывать элементы и ломать тесты. На тестовых устройствах её обычно отключают.
#Инструментальные тесты и профилирование
adb shell pm list instrumentation
Какие раннеры установлены на устройстве.
adb shell am instrument -w <pkg>.test/androidx.test.runner.AndroidJUnitRunner
Запуск всего набора инструментальных тестов. -w ждёт завершения и печатает результат.
adb shell am instrument -w -e class com.example.LoginTest#validCredentials \
<pkg>.test/androidx.test.runner.AndroidJUnitRunner
Один тест или один класс — быстрый цикл при отладке падения.
adb shell am instrument -w -e package com.example.smoke \
-e annotation androidx.test.filters.LargeTest \
<pkg>.test/androidx.test.runner.AndroidJUnitRunner
Фильтры по пакету и аннотации. Так набирается smoke-набор без пересборки.
adb shell dumpsys meminfo <pkg>
Память по категориям. Растущий Private Dirty между итерациями одного сценария — признак утечки.
adb shell dumpsys gfxinfo <pkg> framestats
Тайминги отрисовки кадров. Из этого считаются пропущенные кадры и janky frames.
adb shell top -b -n 1 -o %CPU,RES,CMDLINE | head -15
adb shell pidof <pkg>
Кто ест CPU и память прямо сейчас.
adb shell am start -W -n <pkg>/.MainActivity
Замер времени старта: ThisTime, TotalTime, WaitTime в мс. Дешёвая метрика для отслеживания регрессий холодного старта.
adb shell cmd package compile -m speed -f <pkg>
Принудительная AOT-компиляция. Убирает разброс первых прогонов при замерах производительности.
#Подготовка устройства к прогону
Последовательность, которая снимает большинство нестабильных падений. Годится и как скрипт в CI.
#!/usr/bin/env bash
set -euo pipefail
PKG="com.example.app"
adb wait-for-device
adb shell 'while [ "$(getprop sys.boot_completed)" != 1 ]; do sleep 1; done'
# анимации — главный источник флаки
adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0
# экран не должен гаснуть посреди прогона
adb shell svc power stayon true
adb shell settings put system screen_off_timeout 1800000
# автоповорот выключен, ориентация фиксирована
adb shell settings put system accelerometer_rotation 0
# чистый старт приложения
adb shell pm clear "$PKG"
# буфер логов пуст, чтобы в артефакт попало только своё
adb logcat -c
echo "устройство готово: $(adb shell getprop ro.product.model)"
Идемпотентный скрипт подготовки: можно запускать перед каждым прогоном.
adb shell settings put global window_animation_scale 1
adb shell settings put global transition_animation_scale 1
adb shell settings put global animator_duration_scale 1
adb shell svc power stayon false
Возврат устройства в человеческое состояние после прогона.
| Симптом | Что смотреть первым |
|---|---|
| Элемент не найден, хотя виден | dumpsys window | grep mCurrentFocus — сверху чужой диалог |
| Тест флакует на ожиданиях | анимации не отключены |
| Падает только первый прогон после установки | диалоги разрешений — ставить с -g |
| Работает локально, падает в CI | таймзона и время устройства, adb shell date |
more than one device | -s <serial> или ANDROID_SERIAL |
device unauthorized | принять RSA-ключ на экране; adb kill-server |
| Приложение не видит мок API | adb reverse tcp:PORT tcp:PORT сбрасывается при реконнекте |
| Длинный прогон падает к концу | df -h /data — кончилось место под артефакты |