В помощь мобильному разработчику
Android UI

Советы по созданию плавного и отзывчивого интерфейса для Android

Александр Алексеев

Разработчикам необходимо, чтобы мобильные приложения не только выглядели красиво и имели богатый функционал, но были высокопроизводительными. Разработчики часто задумываются каким образом можно оптимизировать сетевые запросы и фоновые операции, чтобы они исполнялись быстрее. Но пользователи обычно связывают производительность с главным компонентом мобильного приложения, с которым они взаимодействуют: пользовательский интерфейс. В отношении пользовательского интерфейса плавность изображения может определяться как последовательность 60 кадров в секунду (fps), что означает обработку кадра каждые 16 мс. В этом посте будут представлены несколько советов и хитростей по идентификации и отладки пользовательского интерфейса для максимальной производительности.

 

Почему 60 fps?

Анимации и переходы приложения — это просто серии статичных изображений. Хитрость заключается в том, чтобы достаточно быстро отобразить эти отдельные изображения, чтобы обмануть человеческий мозг и заставить его думать, что это непрерывное движение. 60 кадров с секунду — это золотая середина между плавным изображением и падением частоты кадров, заметных человеческому глазу. Более подробно объясняет Кольт Макэнлис (Colt McAnlis) в этом видео. Соответственно на отображение одного кадра тратится около 16 мс. Теперь, когда понятно, к чему нужно стремится, как сделать так, чтобы приложение удовлетворяло требованиям производительности?

 

Поиск проблемы

Случалось ли что-нибудь подобное с вашим приложением?

Спасибо Дугу Силларсу за отличный пример.

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

Приложение не отвечает

Или может будет показано следующее в логах:

 

Android Choreographer предупреждает, что приложение не обеспечивает плавное изображение, что и являлось целью. Собственно он сообщает, что пропускаются  кадры и не получается изображения частотой 60 fps. Это можно исправить! Вот основные действия при идентификации и решения проблем пользовательского интерфейса:

  • Всесторонне оценить производительность пользовательского интерфейса с помощью Systrace
  • Использовать Hierarchy Viewer, чтобы просмотреть и настроить визуальное представление иерархий.
  • Снизить нагрузку наложений настройкой лейаутов и отображением меньшего количества пикселей на экране.
  • Включить StrictMode, чтобы найти и уменьшить количество возможно блокирующих запросов в потоке пользовательского интерфейса.

 

Начало

Подсчет пропущенных кадров

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

 

Эта команда выведет что-то вроде:

 

Цифры никогда не врут, так что очевидно, что есть некоторое количество подвисших кадров (~9%). Нужно продолжить дальше с помощью инструмента  Systrace.

 

Использование инструмента  Systrace

Systrace предоставляет обзор всей  Android системы и показывает происходящие события в определенные интервалы времени.

Начало

Нужно запустить  Systrace на устройстве. Для этого следует открыть  Android Device Monitor.  Здесь присутствует опция, с помощью которой можно запустить  Systrace:

Затем нужно сделать запрос на то, что необходимо отследить. После выбора всех флажков Commonly Used и отмены выбора  Advanced Options создастся файл  trace.html  для обозначенного периода отслеживания.

Вот пример  Systrace на период около 30 секунд:

Systrace

Отлично! Но что это все означает?

Здесь показано некоторое число предупреждений в виде круглых значков в строке   Alerts. Если взглянуть  непосредственно на сам процесс, можно увидеть строку кадров. Кадры,расцвеченные желтым и красным, превышают время рендеринга в 16 мс.

Если кликнуть на предупреждении, то появится обзор проблемы внизу окна отслеживания. Можно получить более подробную информацию об определенном кадре, кликнув на соответствующий ярлык кадра в самом процессе или просто кликнув  Frame в описании предупреждения. Она покажет количество времени, затраченного на данное действие:

Зависшие кадры

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

Снова подвисшие кадры

На примере желтого кадра можно составить общее представление.

Из этого предупреждения ясно, что можно избежать значительного количества работы в  View.OnDraw()  или в Drawable.Draw(), особенно выделений и отрисовок в Bitmaps.  Google по этому поводу дает совет в этом видео.

Понятно, что Adapter.GetView() должен переработать входящий  View, вместо того, чтобы создать новый.

Systrace понятия

Цвет кадра

  • Зеленый: отличная производительность
  • Желтый: хуже идеальной производительности
  • Красный: плохая производительность

 

Запланированная задержка

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

 

Wall длительность

Количество времени, прошедшее с начала исполнения среза до его завершения.

 

CPU длительность

The amount of time the CPU spent processing that slice.

Количество времени, которое тратит CPU на обработку этого среза.

 

Перерисовка наложений

Перерисовка наложений — чрезмерная отрисовка пользовательского интерфейса, результатом которой является медленная работа пользовательского интерфейса (из-за раздутых лейаутов, анимаций и т.п.). Отладка этой проблемы довольна проста. Нужно включить диагностику в настройках  Android устройства: Настройки (Settings) -> Параметры разработчика  (Developer Options) -> Отладка наложения (Debug GPU overdraw) -> Показывать области наложения (Show overdraw areas).

После этого появится множество разных цветов на лейаутах.

  • Белый: нет наложения
  • Синий: 1кратное наложение пикселей
  • Зеленый: 2кратное наложение пикселей
  • Розовый: 3кратное наложение пикселей
  • Красный: 4кратное наложение пикселей

Плохое исполнение лейаутов:

Перерисовка присутствует

 Хорошее исполнение лейаутов:

Нет перерисовки

Далее можно выяснить, почему этот лейаут был перегружен наложениями с помощью инструмента Hierarchy Viewer .

 

Hierarchy Viewer

Для начала нужно узнать как глубоко вложены лейауты. Чем глубже вложены лейауты, тем больше нагрузка на  GPU.

Рассмотрим предыдущий пример неэффективного исполнения лейаута:

Просмотр иерархии интерфейса

Здесь видны 4 уровня вложений, что хуже чем идеально согласно  ListView. Теперь стало лучше.

Просмотр иерархии интерфейса

Остались только три уровня вложений. Однако производительность пользовательского интерфейса все еще не на высоте. Нужно убрать еще один слой.

Просмотр иерархии интерфейса

Намного лучше! Оптимизация всего представления иерархий повысит производительность. Вот тайминги всех этапов настройки лейаута и отрисовки  для доказательства:

  • начальный лейаут: 31 представление / лейаут: 0,754 мс / отрисовка: 7,213 мс
  • улучшенный лейаут: 26 предсталений / лейаут: 0,474 мс / отрисовка: 6,191 мс
  • финальный лейаут: 17 представлений / лейаут: 0,474 мс / отрисовка: 1,888 мс

 

StrictMode

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

  1. Записывает сообщение в LogCat под меткой StrictMode
  2. Отображает диалог (если PenaltyLog() включен )
  3. Аварийно отключает приложение (если PenaltyDeath() включен)

Это поможет разработчику выбрать тип сбоя для проверки на приложении. Включить  StrictMode в  Android приложении можно, вставив в Activity что-нибудь подобное:

 

Итоги

В этом посте были рассмотрены различные инструменты, такие как Systrace, отладка наложений,  Hierarchy Viewer и  StrictMode, чтобы решить проблемы, связанные с производительностью приложения. Пользуясь этими инструментами, разработчик может быть уверенным, что его Android приложения будут иметь прекрасную производительность,  которая обеспечит 60 fps.

Автор: Jon Douglas
ИсточникОфициальный блог Xamarin

Александр Алексеев
Александр Алексеев

Xamarin - разработчик. Работаю с .NET платформой с 2012 года, программирую в основном с использованием C#. За это время успел поработать с ASP.NET, Entity Framework, MSSQL, Git

EntityFramework логотип
Azure DocumentDB логотип

Написать ответ