Разработка пользовательского интерфейса для Android OS основана на основополагающем принципе — использовать как можно меньше элементов! Но в силу разнообразия элементов интерфейса и их комбинаций иногда сложно сказать, какая реализация является наиболее производительной.

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

Контейнеры имеют широкое и разнообразное применение. Это разнообразие порождает головную боль выбора — рациональный набор контейнеров. Давайте рассмотрим частный случай этой задачи.

Эксперимент EGO Creative Innovations

Наиболее популярными элементами управления, которые выступают в качестве контейнеров для Android OS, являются LinearLayout и RelativeLayout. Кроме широкого распространения у этих контролов достаточно большая степень взаимозаменяемости, т. е. возможно достаточно безболезненно один контейнер заменить другим. Как известно, основным отличием данных контейнеров является подход к расположению элементов внутри:

  • LinearLayout — позиционирование основано на порядке расположения составных компонентов внутри;
  • RelativeLayout — необходимо явно указывать относительное расположение элемента.

Для обоснования рационального выбора реализации сравниваемых контейнеров предлагаем использовать следующие критерии:

  • время инициализации графической части;
  • занимаемое количество виртуальной памяти;
  • удобство использования;

Все, кто занимался разработкой пользовательского интерфейса для Android-платформы, согласятся, что использование LinearLayout в большинстве случаев является более удобным в силу простоты расположения элементов внутри по сравнению с RelativeLayout. Но так как удобство использования — это достаточно субъективный критерий и определяется эмпирически, в данной статье этот критерий не будет ключевым в обосновании выбора.

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

Для возможности сравнения производительности LinearLayout и RelativeLayout по заданным критериям было создано тестовое приложение. Для примера было создано два одинаковых внешне элементарных пользовательских интерфейса, которые различаются реализацией интерфейса с использованием LinearLayout и RelativeLayout соответственно.

Интерфейс первого фрагмента содержит 20 рядов по 20 элементов View, которые расположены в LinearLayout, при этом каждый ряд отдельно размещен в собственном LinearLayout, что привело к размещению 20 «лишних» контейнеров. В общем, в первом фрагменте 22 контейнера и 400 элементов контента.

Интерфейс второго фрагмента аналогично содержит 20 рядов по 20 элементов View, которые расположены в RelativeLayout. И, в отличии от LinearLayout, в данной реализации все View расположились в одном контейнере. Таким образом, во втором фрагменте — два контейнера и 400 элементов контента, что на 20 контейнеров меньше, чем в первом фрагменте.

Данные фрагменты имеют один и тот же класс, но разные ссылки на файл лейаута. В теле перегруженного метода OnCreateView фрагмента помещена логика для определения потраченного времени на инициализацию и используемую приложением виртуальную память.

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

Переключение между фрагментами осуществляется с помощью драйвера. Основные элементы приложения показаны на рис. 1-2.

Результаты эксперимента

Ниже представлены результаты, полученные на реальных девайсах.

Мобильное устройство № 1

  • Версия Android SDK — Android Marshmallow (6.0)
  • Разрешение дисплея — 1280×720
  • Диагональ экрана — 5 дюймов
  • Процессор — MediaTek MT6735 4 ядра
  • RAM — 2 Гб

Мобильное устройство № 2

  • Версия Android SDK — Android Nougat (7.0)
  • Разрешение дисплея — 1280×800
  • Диагональ экрана — 8 дюймов
  • Процессор — MediaTek MT8163 4 ядра
  • RAM — 2 Гб

Мобильное устройство № 3

  • Версия Android SDK — Android Oreo (8.1)
  • Разрешение дисплея — 1920×1080
  • Диагональ экрана — 5,5 дюйма
  • Процессор — Qualcomm Snapdragon 625 8 ядер
  • RAM — 4 Гб

Выводы

Как видно из приведенных выше результатов, на всех устройствах время инициализации вью фрагмента с LinearLayout меньше, чем на аналогичном фрагменте с RelativeLayout. Такая же ситуация с занимаемой приложением памятью — фрагмент с LinearLayout занимает меньше оперативной памяти, чем с RelativeLayout.

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

Исходя из полученных результатов, можно сделать вывод, что использование LinearLayout в качестве контейнеров со значительным количеством элементов контента является более предпочтительным. А использовать RelativeLayout следует в случаях невозможности применения LinearLayout.

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

Об авторах: Влад Загубинога — разработчик, Янина Ноэль — бренд-стратег, компания EGO Creative Innovations.