Я хочу выяснить основные проблемы с эффектами макетов и представлений Android. Сейчас я занимаюсь исследованием, но, возможно, у кого-то есть ответы.Как ограничено количество просмотров?
У меня есть RelativeLayout
, который заполнен динамически. В основном приложение загружает поток форума в XML, а затем отображает дерево обсуждений, поэтому каждое сообщение отображается в собственной группе представлений. Я решил не использовать WebView
, потому что я хочу реализовать некоторые функции на стороне клиента, которые должны быть проще выполнять на пользовательских представлениях, чем на HTML-странице.
Однако этот подход имеет серьезный недостаток: он тяжелый.
Первая проблема (я решил) - nesting of views. Теперь это не проблема, мой макет почти плоский, поэтому максимальная глубина 10-12 (с самого верха PhoneWindow $ DecorView, фактическая глубина зависит от данных).
Теперь я достиг следующего предела, который каким-то образом связан с (или вызванным) потреблением ресурсов видами. После загрузки данных приложение некоторое время зависает для создания макета (создает представления и заполняет их данными), и время зависания, похоже, растет линейно с размером данных; и если данные достаточно велики, представление никогда не появится (в конечном итоге система предлагает закрыть приложение, потому что оно не отвечает).
Теперь вопросы:
потребление памяти незначительно зависит от класса представления? Другими словами, существует ли какая-либо существенная разница между
Button
иTextView
, илиImageView
? Я могу прикрепить обработчик кликов к любому виду, чтобы они не сильно отличались в использовании.Действительно ли фоновые изображения влияют на производительность? Если одно и то же изображение установлено в
N
просмотрах, сделает ли оно макетN
раз тяжелее? (Я понимаю, что этот вопрос может выглядеть глупым, но в любом случае.)Изображения с девятью патчами значительно тяжелее обычных? Что лучше: создать
N
виды, где у каждого есть некоторые фоновые изображения, или сделать один видN
раз шире и имеет повторяющийся фон?Учитывая некоторые макеты, что должно быть оптимизировано в первую очередь: общее количество просмотров, уровней вложенности или что-то еще?
Самое интересное. Возможно ли измерить или, по крайней мере, оценить ресурсы, потребляемые деятельностью и ее мнениями? Если я внесу некоторые изменения, как я могу увидеть, что я иду по правильному пути?
UPDATE
Благодаря User117, некоторые вопросы, которые задавали мне выше, теперь ответил. Я использовал средство просмотра иерархии и оптимизировал свой макет: по сравнению с тем, что у меня было раньше, общее количество просмотров теперь уменьшено почти в два раза, а также вложенность.
Однако приложение все еще висит на большой ветке форума.
UPDATE 2
Я подключен отладчик на устройство и обнаружил, что приложение получает из памяти.
Но для меня очень неожиданно возникает ошибка после заполнения макета. Последовательность выглядит следующим образом:
- Все мои взгляды добавлены. Я вижу небольшое замедление, поскольку они добавляются.
- Почти ничего не происходит в течение пары секунд. За это время в журнале генерируется несколько информационных сообщений, они идентичны:
[global] Loaded time zone names for en_US in XXXXms
, единственное различие - это количество миллисекунд. - Появляется сообщение об ошибке из памяти:
[dalvikvm-heap] Out of memory on a N-byte allocation
(действительный размер варьируется). Начинается длинная отчетность об ошибках.
Что это значит? Похоже, что у рендеринга есть свои требования, которые могут быть значительными.
UPDATE 3
Наконец я нашел основной вопрос. Вот скриншот из моего приложения, см. Объяснение ниже изображения.
Каждое сообщение состоит из круглой кнопки, которая показывает или скрывает ответы и красный содержимого кадра справа от кнопки. Это очень просто и требует только 6 просмотров, включая макеты.
Проблема заключается в отступе с этими линиями связи, которые показывают, какое сообщение связано с которым.
В моей текущей реализации отступ состоит из небольших ImageView
, каждый из которых содержит квадратное изображение, которое показывает либо пустое пространство, либо вертикальную линию, или T-образный разъем, либо L-подобный угол. Все эти представления выравниваются друг с другом в пределах большого RelativeLayout
, который содержит все дерево обсуждений.
Это прекрасно работает для небольших и средних деревьев (до нескольких сотен сообщений), но когда я пытаюсь загрузить большое дерево (сообщения 2K +), я получаю результат, описанный в ОБНОВЛЕНИИ 2 выше.
Очевидно, у меня есть две проблемы. Я создаю большое количество просмотров, которые все потребляют память, и эти представления - это ImageView
, для которых требуется больше памяти для рендеринга, поскольку они визуализируют растровое изображение и, следовательно, создают графические кеши (в соответствии с объяснением, данным User117 в комментариях).
Я попытался отключить загрузку изображений в виде отступов, но не получил никакого эффекта. Похоже, что добавить огромное количество просмотров достаточно, чтобы съесть всю доступную память.
Моя другая идея состояла в том, чтобы создать изображение с отступом для каждого сообщения, которое будет содержать все трубы и углы, поэтому каждое сообщение будет иметь единственный отступ в виде вместо 10 или 20. Но это еще более утомительно: у меня есть вне памяти в середине заполнения макета. (Я кэшировал изображения на карте, поэтому не было создано двух растровых изображений с одинаковой последовательностью изображений, что не помогло.)
Итак, я прихожу к выводу, что я в тупике. Можно ли сразу рисовать все эти строки?
Учитывая простую функцию: кнопка с графикой, которая имеет действие OnClick, я мог бы пойти несколько путей: 1) вставить 'Button' с фоновым изображением, 2) вставляет' ImageView', 3) вставить 'TextView ', а затем назначить обработчик кликов этому объекту, независимо от того, какой класс используется. Есть ли разница в производительности среди этих способов? –
@AlexanderDunaev Ну, 'Button' будет использовать визуальные эффекты ОС по умолчанию,' ImageView' загрузит немного больше от вас ресурсов приложения, и 'TextView' содержит дополнительный код измерения/рендеринга текста, а также один и тот же код обработчика прилагается. _индивидуальная разница в временах, полученных этими представлениями для управления/повторного рисования, была бы неуместной. Теперь, если у вас есть около тысячи из них в вашем макете, то общие различия могут быть значительными. Кроме того, 'Button',' ImageButton', 'ImageView',' TextView' и т. Д. Являются _built для конкретной цели и лучше всего подходят для этой цели. –
I второй @ User117 ответ, особенно пункт 4). Не создавайте представления в возможно длинных (иерархических) списках, которые не видны. Вместо этого измените * содержимое * видений, которые видны, путем «прокрутки» данных, которые они содержат в представлении, подобно тому, как ListView и связанные с ним представления. Например. в вашем скриншоте, не более 11 или 12 строк должны быть созданы, каждый из которых содержит родительское-представление, изображение ракурс и текстовый вид с некоторым пользовательским рисунком (линия) л. В целом, не более 36 просмотров в этом случае. –