2016-02-23 2 views
1

Как разработчик Android, мне не нужно знать, насколько эффективнее производительность приложений, объявляя макеты программным способом или XML.Android - Производительность макетов: Programmatic vs XML

Я прочитал this и this вопрос о SO, но ни один из них не ответил на мой вопрос:

Что более производительным: писать макеты программно или объявлять их в XML-файлах?

Обратите внимание, что я только спрашиваю о производительности, я не хочу отвечать на другие факторы.

Кроме того, я ищу очень технический ответ. Если необходимо, укажите ссылки на код AOSP, который оправдывает ваш ответ (вы можете предположить, что версия Android - Marshmallow). Еще лучше было бы указать на эксперимент/документ/бенчмарк, когда время загрузки огромного размера сравнивалось с использованием двух разных способов.

+0

Какую производительность вы пытаетесь достичь? Макеты в конечном итоге скомпилированы в код, поэтому на самом деле нет большой разницы. – Tdorno

+0

Я был бы доволен сравнением времени загрузки Activity, хотя есть некоторые другие критерии для измерения. – FlyingPumba

+0

@Tdorno означает, что XML имеет недостаток, потому что он должен быть обработан в коде? – FlyingPumba

ответ

4

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

Предположим, у вас есть макет:

<LinearLayout xmlns:android="..." 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    ... > 

    <Button 
     android:id="@+id/some_button" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="@drawable/my_button_bg" 
     android:text="Hello World" /> 

    <!-- other views ... --> 

</LinearLayout> 

Что происходит на Android компилирует этот файл в двоичном формате и пакеты, которые в АПК. Когда вы используете LayoutInflater во время выполнения, он загружает блок этого двоичного формата в память и анализирует его, а также строит иерархию представлений из содержимого, очень похожее на то, что вы делаете вручную. Этот синтаксический анализ выполняется в собственном коде, поэтому он, вероятно, гораздо более оптимизирован, чем ваш типичный синтаксический анализ XML в java.

LayoutInflater строит представления, используя отражение, когда встречается с тегом (например, <Button .../>). В первый раз он должен искать конструктор для этого конкретного вида; после этого он будет кэшировать конструктор для более быстрого доступа позже.

Если вы обычно вызываете мутаторы, например button.setText(...), button.setBackground(...) и т. Д., Как правило, эти вызовы называют самими во время инфляции. То есть путь кода, проходящий через конструктор представления, будет выполнять эти мутации на основе атрибутов, проанализированных из двоичного формата XML. Это связано с тем, что LayoutInflater использует конструктор с двумя аргументами, который принимает AttributeSet. Импликация здесь заключается в том, что при создании представлений вручную некоторые из этих методов могут быть вызваны дважды.

Например, возьмите кнопку в образце выше. У кнопок уже есть фон по умолчанию (как это фактически предусмотрено, это интересно, но не очень важно здесь), поэтому даже вызов конструктора с одним аргументом только с Context по-прежнему получает вас Button с фоном по умолчанию. Другими словами, путь кода включает вызов setBackground(...) (или некоторого эквивалента) с фоновым изображением по умолчанию. Затем позже вы должны вызвать setBackground(...) самостоятельно с помощью настраиваемого ресурса, названного в XML-файле. Трудно сказать, какое влияние это имеет, потому что это действительно зависит от реализации отдельных представлений и того, какие мутации вы делаете.


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

  • код имеет тенденцию быть очень многословным
  • Вы не получаете выгоду от всех инструментов, построенных вокруг макетов XML в среде IDE
  • Даже без инструментов, просто файл XML в одиночку дает вы четко представляете иерархию представлений
  • Возможно, вам придется знать об определенных особенностях инфраструктуры пользовательского интерфейса (некоторые из которых могут зависеть от уровня API)
  • Не всегда возможно сопоставить атрибут XML с соответствующим методом мутаторов в java (иногда иногда в зависимости от API lev эль)
  • Расчет размеров становится намного более интересным
  • Запоминание который LayoutParams использовать где большие умственная гимнастика

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

+0

хороший момент, согласился, гораздо более хлопотно сделать это в коде –

+0

@ Karakur отличный ответ. Я закодировал небольшой эксперимент https://github.com/FlyingPumba/AndroidLayoutsPerformanceBenchmark и протестировал его на своем телефоне (Moto G 1st gen). Чтобы загрузить активность с помощью 500 текстовых элементов внутри LinerLayout с помощью XML, требуется в среднем 541 мс. Выполнение того же программно занимает в среднем 380 мс. Это совсем не так. Не могли бы вы дать понять, почему это происходит? Из того, что вы говорите, я ожидаю, что просмотры из XML будут загружаться быстрее. Этот пробел достигает 1 секунды, если я увеличиваю число просмотров до 5000. – FlyingPumba

+0

Мои мысли здесь в том, что даже когда Inflater использует конструктор с двумя аргументами и xml оптимизирован, весь процесс обхода дерева более «дорог» ", чем вы сохраняете, вызывая эти специальные конструкторы и избегая двойного вызова, например,' setBackground() '. – FlyingPumba

Смежные вопросы