Работа с оконным менеджером (wm)

Рейтинг: 40.9% · 8 голосов
Полный курс по Android Debug Bridge: установка, подключение, shell, логи, dumpsys, автоматизация, root, беспроводная отладка. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
android_roman
Сообщения: 45
Зарегистрирован: 11 май 2026, 05:31

Работа с оконным менеджером (wm)

Сообщение android_roman »

АкадемияADB: Android Debug BridgeГлава 13 из 29
Оглавление курса (29)
  1. Введение в Android Debug Bridge
  2. Установка и настройка рабочей среды
  3. Подключение устройства (проводное и беспроводное)
  4. Базовые команды ADB и управление сервером
  5. Команды состояния и перезагрузки
  6. Навигация по файловой системе
  7. Управление пакетами приложений
  8. Логирование с помощью logcat
  9. Системные дампы и диагностика (dumpsys)
  10. Анализ производительности в реальном времени
  11. Эмуляция ввода (input)
  12. Управление Activity и Intent (am)
  13. Работа с оконным менеджером (wm) (вы здесь)
  14. Захват экрана и запись видео
  15. Root-доступ и его применение
  16. Модификация системных настроек через settings
  17. Команды для поставщиков контента (content)
  18. Резервное копирование и восстановление (backup)
  19. Проброс портов и туннелирование
  20. Беспроводная отладка (Wi-Fi)
  21. Взаимодействие с эмуляторами
  22. Написание скриптов на Bash/CMD/PowerShell
  23. ADB в языках программирования
  24. Автоматизация тестирования с ADB
  25. Безопасность и лучшие практики
  26. ADB на Android TV, Wear OS и IoT
  27. Восстановление и низкоуровневые операции
  28. Расширенные возможности оболочки и инструменты
  29. Отладка самого ADB и устранение неполадок
В главе 12 мы командовали Activity через am, теперь опустимся уровнем ниже, к оконному менеджеру. Утилита wm управляет тем, как Android видит экран: разрешением, плотностью пикселей, поворотом, отступами. На практике это превращает один физический телефон в стенд для тестирования верстки под десяток разных устройств. Ни root, ни специальная прошивка не нужны, все команды выполняются от имени пользователя shell.

Что такое wm на самом деле:

На свежих прошивках (Android 11-15) wm это однострочный скрипт в /system/bin, который вызывает cmd window. То есть wm size и cmd window size, одна и та же команда. Полный список подкоманд:

Код: Выделить всё

adb shell wm help
Список заметно отличается между версиями Android, поэтому пример с форума пятилетней давности может не завестись. Ниже для каждой команды отмечаю, где она живая.

wm size, чтение и подмена разрешения:

Без аргументов команда показывает физическое разрешение панели:

Код: Выделить всё

adb shell wm size
Physical size: 1080x2400
Подменяем разрешение (формат ШИРИНАxВЫСОТА в пикселях):

Код: Выделить всё

adb shell wm size 720x1600
Система пересчитает поверхность мгновенно, перезагрузка не нужна. Теперь вывод выглядит так:

Код: Выделить всё

adb shell wm size
Physical size: 1080x2400
Override size: 720x1600
Override хранится в системных настройках и переживает перезагрузку. Вернуть как было:

Код: Выделить всё

adb shell wm size reset
На устройствах с несколькими дисплеями (складные, DeX, авто) есть флаг -d с номером дисплея:

Код: Выделить всё

adb shell wm size -d 1
wm density, плотность пикселей:

Код: Выделить всё

adb shell wm density
Physical density: 420
Density определяет, сколько пикселей приходится на один dp. Формула: ширина_в_dp = ширина_в_px / (density / 160). Телефон 1080x2400 при 420 dpi дает 411 dp по ширине, обычная верстка. Поднимем плотность:

Код: Выделить всё

adb shell wm density 560
Теперь ширина 1080 / 3.5 = 308 dp, и вы видите интерфейс глазами пользователя, который выкрутил "Размер изображения на экране" на максимум. Тексты переносятся, кнопки наезжают друг на друга, тут и вылезают баги верстки. Сброс:

Код: Выделить всё

adb shell wm density reset
Опорные значения: 160 (mdpi), 240 (hdpi), 320 (xhdpi), 480 (xxhdpi), 640 (xxxhdpi). Density тоже переживает ребут, не забывайте про reset.

Рецепты эмуляции устройств для тестов:

Бюджетник с HD+ экраном на вашем флагмане:

Код: Выделить всё

adb shell wm size 720x1600
adb shell wm density 320
720 / 2.0 = 360 dp, классическая ширина недорогих аппаратов.

Планшетная верстка sw600dp на обычном телефоне:

Код: Выделить всё

adb shell wm size 1200x1920
adb shell wm density 320
Override может быть больше физического разрешения, картинка отрисуется с даунскейлом. 1200 / 2.0 = 600 dp, и приложение подхватит ресурсы из layout-sw600dp.

Грабли, на которые наступают все:

Первое. Уже запущенные приложения после смены size/density перерисовываются не всегда корректно. Лечится перезапуском:

Код: Выделить всё

adb shell am force-stop com.example.app
. Лаунчер тоже может поплыть, особенно на One UI и HyperOS, помогает am force-stop лаунчера или ребут.

Второе. Если выставить дикую плотность вроде 40 или 1200, экраном станет невозможно пользоваться. Без паники: adb продолжает работать, вслепую набираем wm density reset.

Третье. Скриншоты screencap (глава 14) снимаются уже в override-разрешении. Для прогонов по матрице экранов это плюс, но не удивляйтесь неродному размеру картинок.

Управление поворотом:

Исторически поворот крутят не через wm, а через settings (подробно о них в главе 16). Сначала выключаем автоповорот, потом задаем ориентацию:

Код: Выделить всё

adb shell settings put system accelerometer_rotation 0
adb shell settings put system user_rotation 1
Значения user_rotation: 0, 1, 2, 3, то есть поворот на 0, 90, 180, 270 градусов от естественной ориентации. У телефонов естественная ориентация портретная, значит 1 это альбомная. У многих планшетов и приставок естественная ориентация альбомная, там шкала сдвинута. Проверка:

Код: Выделить всё

adb shell settings get system user_rotation
1
Два ограничения. user_rotation работает только при выключенном автоповороте (первая команда). И приложение должно разрешать поворот: если Activity жестко прибита через android:screenOrientation="portrait", никакая настройка ее не положит набок.

На Android 12-15 у wm есть и собственная подкоманда:

Код: Выделить всё

adb shell wm user-rotation lock 3
adb shell wm user-rotation free
lock фиксирует поворот, free возвращает автоповорот. Эффект тот же, что у settings, но в одну строку.

wm overscan, некролог и замена:

Команда задавала отступы от краев экрана в пикселях (лево, верх, право, низ), изначально для телевизоров, которые обрезают края картинки:

Код: Выделить всё

adb shell wm overscan 0,0,0,120
Работает это только до Android 10 включительно, там же есть и сброс через wm overscan reset. В Android 11 команду удалили вместе со всем механизмом overscan, на свежих устройствах получите:

Код: Выделить всё

adb shell wm overscan 0,0,0,120
Error: Unknown command: overscan
Чем заменить. Если вы тестировали поведение верстки при срезанных краях, на Android 11+ есть эмуляция выреза камеры через оверлеи:

Код: Выделить всё

adb shell cmd overlay list android | grep cutout
[ ] com.android.internal.display.cutout.emulation.corner
[ ] com.android.internal.display.cutout.emulation.double
[ ] com.android.internal.display.cutout.emulation.hole
[ ] com.android.internal.display.cutout.emulation.tall
[ ] com.android.internal.display.cutout.emulation.waterfall

Код: Выделить всё

adb shell cmd overlay enable com.android.internal.display.cutout.emulation.tall
Выключается через cmd overlay disable с тем же именем. А обрезку на телевизорах теперь лечат калибровкой в меню самого ТВ, к Android TV вернемся в главе 26.

Многооконный режим и am task:

Команды этой группы живут в am, но управляют именно окнами, поэтому разбираем их здесь. Сначала нужно узнать id задачи. Классика:

Код: Выделить всё

adb shell am stack list
На части прошивок Android 13+ вывод переименован (RootTask вместо Stack), а кое-где подкоманду выпилили. Универсальный запасной вариант:

Код: Выделить всё

adb shell dumpsys activity activities | grep "Task{"
* Task{f8a3c21 #74 type=standard A=10287:org.telegram.messenger U=0 visible=true ...}
Число после решетки и есть taskId, здесь 74.

Закрепление экрана (screen pinning), полезно для киоск-сценариев и автотестов, где приложение не должно сворачиваться:

Код: Выделить всё

adb shell am task lock 74
adb shell am task lock stop
Первая команда прибивает задачу на экран, вторая снимает закрепление.

Изменение размеров окна работает только для задач во freeform-режиме. На обычном телефоне его сперва нужно включить (это те же переключатели, что в меню разработчика):

Код: Выделить всё

adb shell settings put global enable_freeform_support 1
adb shell settings put global force_resizable_activities 1
adb reboot
После перезагрузки запускаем приложение сразу в свободном окне:

Код: Выделить всё

adb shell am start --windowingMode 5 -n com.android.settings/.Settings
Коды windowingMode: 1 fullscreen, 2 pinned (картинка в картинке), 5 freeform. Коды 3 и 4 (старый split-screen) удалены начиная с Android 12, поэтому разделение экрана пополам шелл-командой на свежих версиях не запускается, только руками через Recents.

Теперь окно можно двигать и растягивать по координатам left,top,right,bottom в пикселях:

Код: Выделить всё

adb shell am task resizeable 74 2
adb shell am task resize 74 100,200,980,1500
am task resizeable меняет режим ресайза задачи: 0 запрещен, 1 crop_windows, 2 разрешен, 3 разрешен плюс PiP. Если задача не во freeform, am task resize вернет ошибку или молча ничего не сделает, это самый частый вопрос по команде.

Связка с автоматизацией:

Матрица плотностей в один цикл (bash, подробнее о скриптах в главе 22):

Код: Выделить всё

for d in 320 420 560; do
  adb shell wm density $d
  adb shell am force-stop com.example.app
  adb shell am start -n com.example.app/.MainActivity
  sleep 3
  adb exec-out screencap -p > shot_$d.png
done
adb shell wm density reset
Пять минут, и у вас скриншоты приложения под три плотности. Добавьте внешний цикл по wm size и user_rotation, и получится полноценный прогон верстки, который раньше требовал ящика тестовых устройств.

Главное из главы: wm size и wm density подменяют экран на лету и переживают ребут (сбрасывайте явно), поворот делается парой settings put system или wm user-rotation, overscan мертв с Android 11 (замена для тестов отступов это эмуляция cutout), а am task lock/resize дают контроль над окнами, но ресайз требует включенного freeform.
👍3 ❤️3 🔥2 😄 🤔2
✔ Лучший ответ сформирован автоматически — jonlin
android_roman писал(а):Если задача не во freeform, am task resize вернет ошибку или молча ничего не сделает у меня на pixel 7 (android 15) именно молча. оба флага через settings включил, ребутнул, и все равно тишина, пока не перезапустил приложение через am start --windowingMode 5. похоже уже открытые таски сами во freeform не переезжают, может кому сэкономит час
Перейти к ответу →
Аватара пользователя
jonlin
Сообщения: 1
Зарегистрирован: 17 май 2026, 16:10

Re: Работа с оконным менеджером (wm)

Сообщение jonlin »

✔ Лучший ответ — сформирован автоматически
android_roman писал(а):Если задача не во freeform, am task resize вернет ошибку или молча ничего не сделает
у меня на pixel 7 (android 15) именно молча. оба флага через settings включил, ребутнул, и все равно тишина, пока не перезапустил приложение через am start --windowingMode 5. похоже уже открытые таски сами во freeform не переезжают, может кому сэкономит час
👍1 ❤️ 🔥 😄 🤔1
Аватара пользователя
bun42
Сообщения: 1
Зарегистрирован: 15 май 2026, 15:33

Re: Работа с оконным менеджером (wm)

Сообщение bun42 »

а если устройство складное, типа fold? wm size меняет оба экрана или только активный? и как вообще узнать display id внутреннего и внешнего, через dumpsys display из главы про dumpsys?
👍2 ❤️ 🔥 😄 🤔
Аватара пользователя
ansible_enjoyer
Сообщения: 2
Зарегистрирован: 30 май 2026, 23:56

Re: Работа с оконным менеджером (wm)

Сообщение ansible_enjoyer »

подтверждаю грабли с лаунчером. поставил density 160 на старом xiaomi ради эксперимента, после reset иконки так и остались гигантскими. полечилось только am force-stop com.miui.home, ребут даже не понадобился
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
QemuSmith
Сообщения: 1
Зарегистрирован: 01 июн 2026, 14:36

Re: Работа с оконным менеджером (wm)

Сообщение QemuSmith »

android_roman писал(а):У многих планшетов и приставок естественная ориентация альбомная
а есть команда которая прямо покажет естественную ориентацию моего планшета? или только эмпирически, поставить user_rotation 0 и смотреть куда повернулось
👍3 ❤️ 🔥1 😄 🤔
Ответить
← Предыдущая глава
Управление Activity и Intent (am)
Следующая глава →
Захват экрана и запись видео

Все главы курса «ADB: Android Debug Bridge»

Поделиться темой: ✈ Telegram VK

Вернуться в «ADB: Android Debug Bridge»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей