Android DDMS: руководство по окончательной консоли Android

Опубликовано: 2022-03-11

Разработка — непростое дело. Цель продолжает двигаться, новые технологии и домены периодически оживают, новые инструменты появляются время от времени, а языки меняются в том, что кажется управляемым хаосом.

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

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

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

DDMS в Android: мое любимое оружие для самоанализа

К счастью для нас, сообществу Android удалось предоставить так много первоклассных инструментов для самоанализа. Stetho от Facebook является одним из лучших, ARO от AT&T («Оптимизатор ресурсов приложений») несколько старше, но все еще первоклассный, с, вероятно, лучшей консолью мониторинга сети, в то время как LeakCanary использует более ограниченный подход, концентрируясь (и отлично справляется с it) в библиотеке обнаружения утечек памяти во время выполнения. Короче говоря, в инструментах для отладки Android нет недостатка.

Тем не менее, алмаз в короне, инструмент самоанализа, которому можно доверять, когда необходимо извлечь важные, точные и правильно отформатированные данные о поведении вашего приложения во время выполнения, по-прежнему остается старым добрым сервером Dalvik Debug Monitor (DDMS) в Android Studio, который был с нами (увы, малоиспользуемый многими командами) со времен плагина Eclipse для Android.

Насколько важна DDMS в разработке Android? Ну, знание того, что я знаю сейчас о DDMS и мониторинге мобильных приложений в целом, скажем, 5-6 лет назад, будучи менее опытным разработчиком Android, избавило бы меня от многих головных болей и ночей отладки.

Обложка Android DDMS: Отладка разработчиком с помощью DDMS.

А дело в том, что DDMS так просто освоить!

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

Часто задают вопрос о разнице между мобильными разработчиками-новичками и мастерами. Освоение DDMS в Android — или, в общих чертах, возможности профилирования и самоанализа приложений — является одним из таких основных отличий.

Примечание. Чтобы стать первоклассным разработчиком, необходимо использовать лучшие библиотеки, доступные в вашей области. В предыдущей статье Toptal я перечислил некоторые из лучших библиотек для разработчиков, доступных для Android. В некотором смысле эта статья является продолжением статьи о «библиотеке» и охватывает один из многих инструментов Android. Излишне говорить, что если вы хотите улучшить свои навыки разработчика Android, прочитайте ее прямо сейчас!

Краткое руководство по DDMS в Android Studio

А теперь, без лишних слов, давайте теперь углубимся в описание DDMS, одного из лучших инструментов разработчика Android.

Если сравнивать усилия с пользой, вероятно, никакой другой инструмент не сможет улучшить качество вашего приложения и помочь вам найти действительно запутанные и неуловимые ошибки, которые оно может содержать. Но все же по какой-то причине (кому-то лень?) очень многие команды не используют DDMS.

Начнем с ускоренного курса по DDMS:

Доступ к DDMS можно получить через Studio > Tools > Android > Android Device Monitor и нажав кнопку DDMS в меню. Вы также можете разместить его в качестве ярлыка (я делаю) на верхней панели.

После открытия вы увидите следующее:

Скриншот: Доступ к DDMS через Android Device Monitor

Левая панель позволяет выбрать устройство/приложение, а правая консоль предоставляет вам несколько представлений, каждое на своей вкладке, каждое из которых отображает определенный вид вашего приложения.

Основные услуги, предоставляемые сервером Dalvik Debug Monitor:

  • Статистика использования памяти приложения (общая статистика распределения кучи и объектов)
  • Статистика потока приложений
  • Снимок экрана устройства
  • Проводник файлов устройства
  • Подмена входящего звонка и SMS
  • Подмена данных о местоположении
  • Логкэт

Чтобы получить текущее значение памяти кучи, используемое вашим приложением, просто сделайте следующее:

  • Подключите устройство, на котором работает ваше приложение
  • Нажмите кнопку «Обновить кучу», чтобы включить сбор статистики кучи.
  • Откройте вкладку "Куча"
  • Нажмите «Причинить сборщик мусора», чтобы принудительно запустить сборщик мусора. Только после такого прогона начнется сбор данных кучи
  • Держите вкладку открытой, продолжайте работать над своим приложением и периодически повторно нажимайте «Причинить сборщик мусора», чтобы обновить данные статистики кучи.

Эта последняя строка, вероятно, требует дополнительных пояснений. Использование памяти — одна из тех аналитических величин, где ее динамика гораздо важнее исходного значения. Для большинства приложений нас не будет сильно волновать начальное значение использования кучи. Мы будем очень заботиться о прогрессе этого значения, так как оно даст нам четкое представление об одном из настоящих кошмаров, ожидающих мобильных разработчиков, — утечках памяти Android:

Снимок экрана: данные кучи используются для выявления утечки памяти Android в DDMS

Мое использование модуля статистики кучи просто; как часть жизненного цикла разработки приложения, после внесения изменений, которые должны повлиять на использование кучи, я активирую модуль «Cause GC» для запуска сбора статистики, активирую (обычно более одного раза) позиции моего приложения, интенсивно использующие кучу, и периодически «Заставлять GC» обновляться. Если использование кучи продолжает расти, у меня на руках утечка памяти, и мне нужно ее решить (подробности о том, как — ниже). Если нет, и независимо от фактического размера кучи, я в порядке.

Если обнаружена утечка памяти, следующим инструментом, который я буду использовать, является средство отслеживания размещения объектов. Давайте посмотрим, что он может сделать для управления памятью в Android.

Трекер размещения объектов

Проще говоря, средство отслеживания распределения предоставит вам информацию, необходимую для выяснения того, кто «виноват» в текущем размере кучи. Этот модуль сообщит вам, из каких потоков и методов поступили команды распределения в режиме реального времени, что делает его бесценным для анализа памяти в Android.

Чтобы начать отслеживание, сделайте следующее:

  • Выберите соответствующее устройство/процесс, как и раньше.
  • Перейдите на вкладку Allocation Tracker и нажмите Start Tracking, чтобы начать.
  • С этого момента все новые распределения будут отслеживаться
  • Нажмите «Получить распределения», чтобы просмотреть список всех последних распределений (последние с момента последнего «начала»)
  • Чтобы узнать, кто является органом распределения, щелкните определенную строку в списке.

Средство отслеживания размещения объектов в DDMS, пользовательский интерфейс

Теперь, по моему собственному опыту, выполнение действий с интенсивным выделением ресурсов в вашем приложении с последующим нажатием кнопки «Получить распределения» для просмотра счетчиков распределения обычно должно напрямую направлять вас к утечке; иногда, когда утечка нелинейна (т. е. происходит время от времени), ИЛИ когда ваше приложение содержит несколько утечек, которые могут не работать. В таких случаях, а я сталкивался не со многими из них, вам нужно будет прибегнуть к ручному созданию файла дампа HPROF и его анализу. Анализ памяти и управление памятью Android не будут подробно рассматриваться в этой статье. См. здесь некоторые выводы.

Консоль Thread Info: использование процессора Android стало проще

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

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

Во всех мобильных приложениях разные потоки будут конкурировать за процессорное время. Их просто не хватает, чтобы их обойти. Что произойдет, если по какой-либо причине один или несколько таких потоков не получат нужного им времени выполнения? Обычно плохие вещи. Система не будет вести себя так, как вы планировали, что всегда является плохой идеей. Потенциальными причинами этой проблемы могут быть установка низкого приоритета, одновременное выполнение других потоков с установкой для себя чрезмерно высокого приоритета, трата времени на мониторы синхронизации и многое другое. Все это, как известно , трудно обнаружить только с помощью проверки кода.

Консоль потоков Android DDMS спешит на помощь!

Консоль информации о потоке в DDMS, пользовательский интерфейс

Когда вы войдете в представление потока, вы увидите список, состоящий из записей потока, каждый из которых содержит имя и идентификатор потока, а также два дополнительных счетчика, называемых utime и stime. Utime измеряет общее время, затрачиваемое потоком на выполнение пользовательского кода (подумайте о ваших функциях и сторонних библиотеках), а stime измеряет общее время, затрачиваемое на системный код (сон, синхронизация, системные вызовы — много). Первый — utime — обычно будет для нас более интересным, хотя я могу вспомнить проблемы, которые в основном будут проявляться счетчиком времени.

Итак, наш код работает, включая несколько потоков, и мы хотим убедиться, что все наши потоки получают свою долю процессорного времени. Для этого мы сначала даем нашей системе поработать какое-то время, а затем открываем вкладку потока и начинаем искать «своеобразные» значения utime. Ноль, безусловно, может представлять собой проблему — поток буквально не получает процессорного времени и не использует ЦП. Но чрезмерно высокие значения могут представлять другой аспект той же проблемы: а именно, потоки, приоритет которых настолько высок, что другие могут голодать.

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

Совет: Никогда не используйте имя потока по умолчанию. Это ничего не значит, и вы, как правило, не сможете обнаружить это в представлениях DDMS. вместо этого всякий раз, когда вы создаете поток или извлекаете его из пула потоков, начинайте взаимодействие с присвоения ему понятного имени. Это сделает вашу жизнь намного проще, чем отладка/профилирование вашей системы. Обычно я добавляю имя приложения, чтобы различать потоки, сгенерированные Android, и потоки, созданные моим собственным кодом, например: MyApp-server-connector, MyApp-db-interactor и т. д.

Совет: Приоритет потока обозначает (грубо говоря) количество процессорного времени, которое ему будет предоставлено планировщиком. Приоритет, назначенный вашим рабочим потокам, имеет решающее значение для общей производительности и «плавности» вашего приложения, и во многих случаях может быть разницей между плавным быстрым поведением и неровным медленным. Правило здесь простое: приоритет по умолчанию, назначенный Android, то есть NORMAL=5, почти всегда не тот, который вы хотите использовать. Вместо этого для большинства рабочих потоков вам нужно меньшее влияние на общее использование ЦП. Для этого при запуске потока установите его приоритет на меньшее значение, я обычно использую приоритет = 3.

Консоль сетевой статистики

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

Ось Y на сетевой диаграмме представляет скорость передачи данных, измеренную в КБ/сек, а ось X — прошедшее время в секундах. Поэтому, чтобы получить быструю оценку размера передачи, попробуйте оценить площадь соответствующего шипа. Через некоторое время это становится довольно легко.

Обратите внимание, что после входа в эту консоль вам нужно будет нажать верхнюю кнопку «включить», чтобы начали появляться сетевые измерения.

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

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

Как только такая закономерность обнаружена, а визуальное отображение пакетов в сетевой консоли упрощает задачу, сразу же подумайте о пакетной обработке. Могу ли я объединить несколько небольших передач в одну большую? Влияние этого изменения на аккумулятор обязательно переместит приложения из разряда аккумуляторов в категорию «хорошее поведение»!

Консоль сетевой статистики в DDMS

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

Хотя вы редко будете использовать эту информацию, обратите внимание, что DDMS использует стек Android Debug Bridge (ADB) для передачи данных обратно/с устройства. Если DDMS не может отобразить ваше приложение или зависает в середине сеанса DDMS, лучше всего открыть консоль и ввести:

 adb devices

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

 adb kill-server adb devices # restarts the adb server and displays all detected devices

Если у вас по-прежнему возникают проблемы, а ваше приложение установлено на физическом устройстве, попробуйте отключить все экземпляры эмулятора. Почему? Поскольку DDMS подключается как к экземплярам физических устройств, так и к экземплярам эмулятора, по умолчанию используется последнее.

Пример реального использования DDMS: приложение останавливается (не падает, а просто останавливается). Пользователь немедленно бросается на ближайшую рабочую станцию, подключается к USB и открывает DDMS в режиме просмотра потоков, чтобы найти стек потоков » неудавшийся поток » трассировку стека — в моем случае из-за тупиковой ситуации синхронизации, которая, будучи однажды обнаруженной, легко решается переключением.

Совет: если стандартной оперативной памяти, выделенной вашему приложению Android, недостаточно, как это может случиться, например, для приложений с интенсивным использованием мультимедиа, обратите внимание, что вы можете получить на 15-20% больше памяти на большинстве устройств, подняв флаг манифеста _ largeHeap. : https://developer.android.com/guide/topics/manifest/application-element.html_

Эмуляция состояния устройства в Android DDMS

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

Тривиальным примером последнего может быть приложение GPS. Большинство из нас не разрабатывает такие приложения (увы, рынок недостаточно велик…), но тем не менее, во многих случаях мы развертываем логику, которая зависит от местоположения, будь то простое представление карты текущего положения пользователя, отслеживание маршрута , или отображение данных с учетом местоположения.

Тестирование таких условий, чувствительных к состоянию, общеизвестно сложно, иногда сложнее, чем написание фактического кода. Если у вас есть физическое устройство с SIM-картой, вы, конечно, можете совершать и принимать звонки и SMS. Изменить статус телефонии вашего устройства намного сложнее, но все же можно сделать. Сменить тестовое место может быть сложнее, хотя можно прогуляться по городу с ноутбуком…

Но все же — как мы будем обрабатывать экземпляры эмулятора? Как мы можем проверить их на наличие этих изменений?

Пример эмуляции состояния устройства в DDMS

DDMS снова на помощь. Одной из сильных, но часто упускаемых из виду функций DDMS является ее способность создавать («подделывать») фиктивные события в работающем экземпляре эмулятора. DDMS может звонить с определенного номера на эмулятор, отправлять SMS, изменять данные о статусе телефонии и многое другое.

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

Активировать статус и действия телефонии довольно просто:

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

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

Все становится интереснее, когда дело доходит до насмешки над новой локацией.

Если все, к чему вы стремитесь, — это установить новое местоположение для вашего экземпляра эмулятора, выберите «Вручную», установите желаемые значения широты/долготы и нажмите «Отправить».

Ручное управление местоположением, используемое для спуфинга в DDMS

Но что, если вместо установки одного фиксированного местоположения вы хотите, чтобы ваше приложение проходило по заранее заданному маршруту — например, изучите его поведение, когда пользователь путешествует из одного города в другой? Такой тест может иметь большое значение для любого приложения с поддержкой карты, а также других приложений, чувствительных к местоположению, которые устанавливают свое окно данных для каждого местоположения пользователя. Здесь вы захотите увидеть, что смещение местоположения с разной скоростью будет поддерживать актуальность отображаемого окна данных.

Для этого мы будем использовать специальный формат под названием KML, который был специально разработан для использования с Google Планета Земля и представляет маршруты или пути в виде набора связанных точек в пространстве, которые могут быть получены с помощью устройств с поддержкой GPS.

GPX — это альтернативный формат пути, поддерживаемый DDMS. Для всех практических целей эти два устройства следует считать взаимозаменяемыми при использовании для спуфинга мобильного местоположения.

Давайте теперь пройдемся по этапам настройки фиктивного маршрута в эмуляторе.

  1. Создайте маршрут. Безусловно, самым простым способом было бы использовать параметр направления Google Maps, задав соответствующий пункт отправления и пункт назначения.

Подмена местоположения в DDMS с помощью Google Maps

  1. Как только маршрут отобразится на карте, перейдите в адресную строку и скопируйте URL-адрес.

  2. Имея URL-адрес в буфере обмена, перейдите в GPS-визуализатор, вставьте его в текстовое поле «Указать URL-адрес» и нажмите кнопку «Преобразовать»:

Подмена местоположения DDMS: настройка GPS Wisualizer

и нажмите, чтобы загрузить полученный файл GPX (с несколько запутанным именем, например, 20170520030103-22192-data.gpx)

  1. Вернувшись к DDMS Location Control, откройте вкладку GPX, нажмите «Загрузить GPX» и выберите только что загруженный файл.

Импорт GPX в DDMS Location Control

  1. Были сделаны! Теперь вы можете перемещаться между различными точками маршрута, нажимая кнопки «Назад» и «Вперед» или нажимая кнопку «Воспроизвести», чтобы автоматически проходить маршрут с заданной скоростью.

Вам не нужно создавать свой собственный маршрут. Множество маршрутов для загрузки с таких сайтов, как OpenStreetMap (см. раздел «GPS-трассы»).

Наконец, обратите внимание, что в отличие от старых версий DDMS, где загрузка файла маршрута была легкой задачей, новые версии могут потребовать проб и ошибок при загрузке определенного маршрута.

Например, оказывается, что DDMS поддерживает только GPX 1.1. Для новых версий GPX может потребоваться ручная настройка.

Кроме того, формат путевых точек GPX больше не поддерживается. Вместо этого используйте формат трека GPX:

 <trk> <name /> <cmt /> <trkseg> <trkpt lat="27.0512" lon="-80.4324"> <ele>0</ele> <time>2017-02-02T08:01:41Z</time> </trkpt> </trkseg> </trk>

Отладка Android: час в неделю имеет значение!

Хватит теории! Пришло время для некоторой практики. Я предлагаю, предполагая, что вы являетесь разработчиком Android, начиная со своего следующего проекта, вы должны посвятить всего один час в неделю для самоанализа производительности вашего приложения с помощью DDMS.

Вы будете удивлены количеством качественной информации (т. е. информации, которая может быть использована для немедленного улучшения состояния вашего приложения), которую вы получите!

Android DDMS, как я неоднократно наблюдал у начинающих разработчиков, — это инструмент, который может значительно улучшить возможности разработчика, при условии, что он освоен и правильно используется. Способность разработчика Android создавать первоклассные системы буквально повысится на одну-две ступени, как только он задействует весь потенциал DDMS в разработке Android. Таким образом, выделение нескольких часов для эффективного использования DDMS звучит как разумное вложение, поскольку оно может значительно повысить производительность и эффективность Android.

Будь одним из умных парней. Используй это.