DroidShoter — скриншоты приложения на разных разрешениях экрана, используя одно устройство и Adb

    Как известно, Андроид устройств существует много… очень много. Это дает нам огромное число экранов, с различным сочетанием разрешения и плотности пикселей, что значительно усложняет разработку приложений. В определенный момент захотелось постараться упростить проверку приложения на разных экранах и избежать запуска на многих устройствах и эмуляторах. Анализ проблемы показал, что все необходимое для решения проблемы есть и, используя Adb, можно обойтись одним подключенным устройством. В итоге была разработана кроссплатформенная утилита для автоматического сохранения скриншотов приложения на разных параметрах экрана одного устройства, не требующая никаких дополнительных манипуляций с исходным кодом приложения (с эмуляторами также все работает). После работы утилиты получаются скриншоты приложения в том виде, в каком оно выглядит на различных устройствах. В дальнейшем, используя полученные скриншоты, можно выявлять артефакты отображения приложения и анализировать оптимальность лэйаутов.

    DroidShoter main


    Quick start


    Чтобы не обременять чтением людей, не интересующихся деталями разработки приложения, приведу сразу краткую информацию по работе с программой.
    • Скачать можно на GitHub в секции Releases. К сожалению, из-за политики GitHub, невозможно приложить *.jar файлы в чистом виде, поэтому пришлось обернуть в zip архив.
    • Требования: установленная Java (JRE достаточно) и Adb.
    • Запуск: двойной клик на DroidShoter.jar файле или команда java -jar DroidShoter.jar в терминале.

    Подробные инструкции со ссылками на Java и Adb находятся на GitHub
    Само использование DroidShoter крайне простое: запускаем утилиту, выбираем устройство, задаем параметры и нажимаем «Start!».

    Пример результата работы программы Вы можете найти под спойлером в конце статьи.

    Внимание! Появилось сообщение о проблемах с Samsung Tab S (SM-T700) с официальной прошивкой Android 5.0.2. Если решитесь использовать утилиту с данным девайсом, будьте готовы, что может понадобиться сбросить настройки. На других устройствах от Samsung проблем не обнаружено.

    Немного деталей


    Согласно официальной документации Google, по своему размеру экраны делятся на: small, normal, large и xlarge; по плотности пикселей: ldpi, mdpi, hdpi, xhdpi:
    screen sizes


    Видно, что многообразие комбинаций экранов возникает из пересечения возможного размера и плотности пикселей. При этом комбинация размера экрана и плотности пикселей определяет его разрешение. Таким образом, можно выделить две базовые характеристики, в достаточной степени характеризующие экраны: разрешение и плотность пикселей. Именно данные характеристики мы и можем менять при помощи Adb. Также мы можем использовать Adb для снятия скриншотов, а значит нам ничего не мешает пройтись по разным комбинациям параметров экрана и делать скриншоты на каждом из них. Именно этот процесс и захотелось автоматизировать.

    Для начала нужно было научиться забирать параметры экрана. И если для устройств, начиная с Android 4.3, проблем не было (парсим вывод команд «wm size» и «wm density»), то, для остальных необходимо было найти иной метод. В результате я использовал команду «dumpsys window», находя в выводе результата строку, наподобие «init=480x800 240dpi». К сожалению, некоторые устройства (пока только один телефон от Sharp) при таком подходе не выдают density и утилитой поддерживаться не будут.

    Для изменения параметров дисплея используются следующие команды Adb shell:
    • wm size [WxH] (начиная с Android 4.3) и am display-size [WxH] (до 4.3.) – для изменения разрешения экрана
    • wm density [value] (начиная с Android 4.3) и am display-size [value] (до 4.3.) – для изменения плотности пикселей
    • Для сброса параметров дисплея используются указанные выше команды с “reset” вместо устанавливаемых параметров.

    К сожалению, при изменении конфигурации экрана системные элементы (status bar, например) могут быть неверно отрисованы. Данная проблема кроется в Android и решить ее не удалось. Однако это не мешает самому приложению отображаться корректно.

    В общем-то, к данному моменту, было уже ясно, что все необходимое для работы есть и утилите – быть. Дело осталось за непосредственной разработкой. В качестве языка я использовал Java, как наиболее близкий мне язык программирования на данный момент и Swing фреймворк для работы с UI. Кроме того, для Java есть замечательная библиотека ddmlib, значительно упрощающая работу с Adb.

    В DroidShoter заложена довольно простая на данный момент базовая логика. При выборе устройства определяются физические параметры экрана, и на их основе выстраивается порядок параметров дисплея для последующей работы. Затем, после нажатия на «Start», начинается процесс смены параметров экрана и снятия скриншотов.

    В качестве очереди параметров дисплея используются все комбинации разрешения экрана и значения плотности пикселей из «базовых», которые меньше физических параметров устройства. Т.е. для экрана с физическим разрешением 720x1280, разрешение 1020x1980 использоваться не будет. То же самое и с плотностью 320 при физической плотности 240.

    Строго говоря, Adb позволяет использовать параметры, превышающие физические показатели устройства, однако на данный момент я решил отказаться от их использования, т.к. возникнет потеря некоторых пикселей и внешний вид приложения не будет соответствовать реальному (к примеру, в списках могут вообще выпасть разделители элементов).

    Базовые параметры:
    Dpi Разрешение экрана — максимальнаая плотность пикселей для разрешения
    XXXHDPI — 640
    DPI_560 — 560
    XXHDPI — 480
    DPI_420 — 420
    XHDPI — 320
    HDPI — 240
    MDPI — 160
    2560x1600 — XHDPI
    2560x1440 — DPI_560
    1920x1200 — DPI_560
    1920x1080 — DPI_560
    1280x768 — DPI_420
    1280x720 — DPI_420
    854x480 — HDPI
    800x480 — HDPI
    480x320 — MDPI
    320x240 — MDPI



    Логика была обрамлена дополнительными фичами для удобства:
    • Автоматическое определение подключения / отключения устройств
    • Возможность указать папку для скриншотов (поддерживается и относительный и абсолютный пути)
    • Указание префикса имени файлов скриншотов. Наименование происходит по шаблону: [prefix][width]x[height]_[density]
    • Возможность задать задержку перед снятием скриншота после смены режима (необходимо для того, чтобы позволить activity выполнить требующие время операции, например, получить с сервера данные)
    • Сохранение списка активных режимов работы для каждого устройства (после перезапуска DroidShoter, снимутся галочки с режимов, которые были деактивированы в последний раз)
    • Автоматический поиск Adb в ANDROID_HOME переменной. Сохранение пути к Adb, если пользователь указал его вручную
    • Отдельная кнопка для сброса параметров экрана к физическим. Кнопка введена на всякий случай, необходимости в ее реальном использовании не возникло.

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

    С точки зрения операционной системы, смена параметров дисплея – это изменение конфигурации экрана, что влечет за собой стандартный процесс пересоздания текущей activity. Смена конфигурации происходит по параметру screenSize и может быть перехвачена в activity путем регистрации в manifest с тэгом
    android:configChanges="screenSize"
    

    Отсюда вытекает дополнительный плюс DroidShoter: тестируется корректность восстановления приложением состояния после изменения конфигурации.

    Пример результата работы DroidShoter:
    Использовался планшет Nexus 7 (2013) и родное приложение «Калькулятор». Калькулятор интересен тем, что при разных разрешениях экрана по разному отображаются дополнительные функции на зеленом фоне, что наглядно показывает смену layout.
    Содержимое папки screenshots
    image

    1200x1920_MDPI
    image

    768x1280_XHDPI
    image

    480x854_MDPI
    image

    320x480_MDPI
    image

    Видео работы
    На видео размер контента уменьшается, однако в действительности экран устройства заполняется практически полностью.
    Смена разрешения происходит примерно раз в 5 секунд.




    План развития DroidShoter, если программа будет востребована сообществом:
    • Поддержка смены ориентации
    • Поддержка смены локализации
    • Автоматический запуск различных экранов приложения (с необходимыми Intent extra)
    • Обеспечение интеграции в CI системы

    Ваши идеи, проблемы и предложения приветствуются в комментариях, в виде issue на GitHub или могут быть отправлены личным сообщением.

    P.S. Ни одно устройство в процессе работы не пострадало.
    Снова Samsung отличились (еще со времен разработки Intent Sender плагина к IDEA обижен на них): Samsung Tab S (SM-T700) ушел в ребут после нескольких скриншотов и впоследствии не запустился (только через hard reset).
    Будет ли полезен для Вас DroidShoter?

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Поделиться публикацией
    Ммм, длинные выходные!
    Самое время просмотреть заказы на Фрилансим.
    Мне повезёт!
    Реклама
    Комментарии 11
    • +1
      Здорово сделано, должно быть неплохо экономит время! Интересно, есть что-либо подобное для iOS?
      • 0
        Лень делает из тестировщика — программиста!
        • 0
          Отличный инструмент. Сэкономил много сил на проекте при оптимизации дизайна под разные экраны. Развивай дальше!
          • 0
            Вот большое вам спасибо!
            • 0
              Подозреваю, что скрины на большом количестве устройств будут отнимать много времени на запуск разных образов эмулятора. Было бы нереально круто предоставлять эту утилиту как сервис — отправил apk, а тебе в ответ быстро с нескольких десятков серверов отрисовались скрины и отправились в ответ.

              Upd. Невнимательно прочитал, у вас по факту один образ с изменением параметров экрана. Было бы круто иметь много образов разных устройств и версий андроида.
              • +1
                Да, используется один девайс / эмулятор. С версиями Android конечно не так все просто — нужно в любом случае несколько устройств. По поводу онлайн сервиса — была подобная мысль, и даже есть идея реализации. Осталось найти время :)
              • 0
                а улучшите если можно программу, чтобы могло коннектиться по TCP как adb connect IP, а не только через провод. или пользовалось существующим подключением. было бы удобно через adbWireless юзать
                • 0
                  Хорошая идея, спасибо. Внесу в to-do лист.
                • 0
                  Тоже писал что-то подобное, идет захват экрана через adb screen, дальше соответственно скриншот отображается и можно нажать или сделать свап на этом скриншоте и команды tap и swap передаются на устройство. Удобно, когда у девайса нет экрана и нужно как-то отладить что-нибудь, но fps конечно ни к черту. Плюс если у девайса нет тач драйвера, то можно отправлять эмуляцию мыши.
                  • +1
                    Кстати хорошую мысль lampa предложил. Вот бы в программу добавить еще 2 кнопки "Take screenshot" & "Next mode"
                    Тогда можно будет для каждого размера экрана проверить разные состояния приложения, а не только как отображается после открытия активити.
                    Спасибо за утилиту!
                    • +1
                      Отличная идея. Добавил в issue на GitHub

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.