android studio оптимизация приложения

Пять шагов по оптимизации производительности приложения для Андроид

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

До создания серьезных приложения со сложной структурой View и Layout’ов мы особо не задумывались над тем, как простые и логичные действия в стиле «смотрите, я набросал дизайн из лэйаутов» могут серьезно замедлить работу всей программы.

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

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

Итак. Исходная точка (то, как это все выглядело ДО оптимизации)

Дизайн приложения был создан из «правильной» кучи около двух сотен View и десятка Layout’ов. Загрузка игрового поля происходила около 5 секунд, а почти каждое действие зависало еще на 1-2 секунды. И если на прогрессивных устройствах и эмуляторах лаги были практически незаметны, то на большинстве менее современных устройств картина выглядела достаточно печальной.

5af39df0a17341ae86e25d38a35424d5

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

Часть знаний, которыми я хочу поделиться, мы нашли здесь — классные видео-уроки с русскими субтитрами (рекомендую), часть — на Хабре, часть — в глубинах Интернета, на том же сайте Google Developers.

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

И вот, как это происходило.

Шаг 1. Измерение

По сути это даже не шаг, а настойчивая рекомендация постоянно измерять свою производительность. Для этого в Андроид Студио предусмотрено несколько специальных программ: Android Device Monitor с HierarhyViewer, SystemTracing, Method Profiling; Android Monitor с Memory, CPU и GPU мониторами. Описывать их работу не цель данной статьи, вы легко можете найти гайды здесь же, на Хабре, или в упомянутых видео-уроках.

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

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

Шаг 2. Оптимизация иерархии и снижение веса

Основная потеря производительности приложений происходит при пересчете и перерисовке отображенных Layout’ов. Причем чем «тяжелее» лэйаут — тем дольше происходит перерасчет его показателей. И тут надо обратить внимание на следующие моменты:

— в вашей иерархии не должно быть вложенных LinearLayout с параметрами «weigh» (вес). Измерение такого лэйаута занимает в два (три, четыре! — в зависимости от вложенности) больше времени. Лучше заменить эту конструкцию на GridLayout (или support.v7.GridLayout для API меньше 21);
— некоторые LinearLayout можно заменить на RelativeLayout, тем самым убрав дополнительные вложения, например;
— оказывается, RelativeLayout также измеряется дважды. Где возможно — его нужно заменить на более «легкий» FrameLayout.

Изучив нашу разметку мы с ужасом обнаружили, что в ней есть вложенные до четырех (!) раз LinearLayout с параметром вес, игровое поле состоит из почти сотни RelativeLayout (клетки поля), а некоторые Layout просто не нужны.

(Зеленым отмечено допустимое вложение, желтым — нежелательное, оранжевым — опасное, красным — «никогда-так-не-делайте!»)

f66a9e5674f84cbc8d9f5c6bb539b501

После этого мы немного переработали структуру. «Персонажа» вынесли в отдельный фрагмент с RelativeLayout, все вложенные Linear заменили на (один!) support.v7.GridLayout, а все RelativeLayout (на скрине их не видно — это клетки поля) заменили на FrameLayout. Получилось и симпатишней и производительней.

212f14be462c43f8bfe43ac98ec8227e

Однако до конца наши проблемы это не решило, и мы пошли дальше.

Шаг 3. Лишняя перерисовка (Overdraw)

Оказалось, что Андроид тщательно прорисовывает каждую картинку, каждый background у каждого View на экране. Здесь он, конечно, молодец. Но что делать, если одни изображения перекрывают другие, бэкграунды накладываются и часть этой прорисовки становится абсолютно ненужной? Правильно — отключать все, что не видно и не нужно.

Измерить наложение перерисовки оказывается очень просто: на своем устройстве в «Параметрах разработчика» нужно включить «Показывать превышение GPU», запустить приложение и посмотреть на экран.

Цвета View-элементов покажут, насколько у вас все хорошо (или плохо).

Свой цвет — уровень 0, «идеально»
Синий цвет — уровень 1, «нормально.
Зеленый цвет — уровень 2, „допустимо“.
Светло-красный цвет — уровень 3, „нежелательно“.
Красный цвет — уровень 4+, „не дай бог“.

Наша картинка вновь ввергла нас в ужас:

e21594635d2c4e12b4ef591c4b7e981f

Нам пришлось снова пройтись по всей разметке и отключить background там, где он оказался лишним. Не забыли и про основной бэк приложения — одной простой строчкой:

В теме приложения выключили и его. И вот что получилось в итоге. Может и не везде идеально, но вполне допустимо. (Почти все View опустились на 3 уровня!)

dcd2437623a84c42beeb3b62891e0de2

Шаг 4. Кэширование — ключ к успеху

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

eebaa469c178418d8558190b7081e7b0

С кэшированием до этого никто из нас не сталкивался, но тут нас выручил один хороший человек со StackOverflow и подсказал простой код:

Применив который, лично я вообще практически забыл, что такое лаги.

Шаг 5. „А это — под укроп!“

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

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

— создавайте поменьше „ненужных“ циклов. Если что-то можно сделать без них — делайте без них;
— не создавайте переменных в цикле. Лучше создать их за его пределами, а в цикле просто обновлять;
— если есть необходимость обратиться к ресурсам неоднократно (с помощью gerResources() или же просто в другой класс/массив, например, myList.get (0)) — лучше запишите полученный результат в новую переменную и используйте ее: int myItem = myList.get(0); — это тоже подарит вашему приложению миллисекунды свободного времени;
— по возможности используйте статические методы (если нет необходимости обращаться к самому классу);
— ну и классический способ: на финальном этапе программирования убирайте инкапсуляцию (геттеры и сеттеры) и обращайтесь к переменной напрямую.

Подводя итог

Уверен, что сделанные шаги не являются окончательными и всегда будет „место под укроп“, до которого мы не добрались. Всегда готов узнать о шаге №6, 7… и даже №157, если вы захотите ими поделиться в комментариях. Более того, за „науку“ буду благодарен.

А пока, резюмируем, что же нужно сделать, чтобы ваше приложение начало „летать“:

1. Измерьте производительность своего приложения и найдите источник проблемы. Может у вас это будет не шрифт, а, например, утечка памяти (включаем Memory Monitor);
2. Оптимизируйте структуру и иерархию View (включаем HierarhyViewer и здравый смысл);
3. Убираем везде все ненужные бэки, включая background приложения (в этом случае учтите, что для корректного отображения вам все равно понадобится общий бэк);
4. Смотрим на часто используемые ресурсы/загрузки/картинки/шрифты и кэшируем их;
5. Делаем оптимизацию программного кода.

В итоге, после всех этих шагов, картинка трассинга приложения стала выглядеть вот так:

e43f68e3853c4aea85a7940f6eb9a1db

задержки практически исчезли (или стали незаметны), что нас вполне устроило.

Ну и конечно, первая мысль, которая пришла ко мне в голову после всей нашей оптимизации: „Вау! Теперь же можно добавить еще больше View и Layout на основной экран!“

Источник

Уменьшаем время сборки ваших Android-проектов

Доброе утро! Начинаем понедельник с материала, перевод которого подготовлен специально для студентов курса «Android-разработчик. Продвинутый курс».

image loader

Недавно я переносил кодовую базу Android в Kure на AndroidX. Мне показалось, что это прекрасная возможность поработать над скоростью сборки проекта. У Gradle всегда была плохая репутация из-за медлительности и ресурсоемкости, но я был очень удивлен, что незначительные изменения в конфигурации сборки могут так значительно увеличить ее скорость.

Посмотрите на показатели сканирования сборки до/после оптимизации


до оптимизации

efssu62faz4yoi92zvmssa1pf0m
после оптимизации ️️

Снизились с 5,5 минут до 17 секунд?? С ума сойти!

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

Прежде всего!

Перед тем, как начать оптимизацию, важно протестировать наш проект, чтобы узнать, сколько времени требуется на его сборку. Gradle имеет удобную опцию сканирования, которую вы можете использовать для анализа производительности вашей задачи. Запустите терминал в Android Studio и выполните следующую команду:

После успешного завершения сборки вам будет предложено принять условия обслуживания, чтобы загрузить результаты сканирования. Введите yes, чтобы продолжить. После завершения публикации вы получите ссылку на терминал для проверки сканирования. Откройте ее.

На сайте есть довольно много опций, но для краткости мы рассмотрим только то, что является наиболее важным.

В Summary отображается сводная информация о выполненных задачах и времени их выполнения. Но что нас здесь интересует, так это раздел Performance. Он делает более подробную разбивку общего времени сборки, как показано ниже.

onn he0w k

В разделе Performance есть вкладка Settings and suggestions, в которой приведены рекомендации по улучшению скорости сборки. Давайте посмотрим на них.

В этом разделе мы можем найти несколько простых исправлений для повышения скорости. Итак, давайте продолжим и применим эти исправления в нашем проекте.

Шаг № 1: Обновите инструменты

Команда Android постоянно совершенствует и развивает систему сборки. Таким образом, в большинстве случаев вы можете получить значительное улучшение, просто установив последнюю версию инструментария.

Во время этого рефакторинга наш проект был на версии 3.2.1 плагина Gradle для Android Studio (на несколько версий старше, чем последний выпуск).

Вы можете перейти по этой ссылке, чтобы получить последнюю версию Gradle Plugin. На момент написания этого поста последней была версия 3.4.0.

Но здесь есть подвох, о котором мы должны помнить:

(Примечание: При использовании Gradle версии 5.0 или выше размер памяти демона Gradle по умолчанию уменьшается с 1 ГБ до 512 МБ. Это может привести к снижению производительности сборки. Чтобы переопределить этот параметр по умолчанию, укажите размер памяти для демона Gradle в файле gradle.properties вашего проекта.)

При использовании Gradle 5.0 и выше нам нужно будет явно увеличить размер памяти, чтобы скорость нашей сборки не ухудшилась. Мы вернемся к этому через минуту.

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

Вы столкнетесь с ошибкой при использовании Kotlin, если версия плагина Kotlin Gradle меньше 1.3.0. Если это так, воспользуйтесь подсказкой IDE, чтобы обновить Gradle плагин для Kotlin до последней версии (на момент написания этой статьи это версия 1.3.31).

Хорошо, давайте снова запустим сборку из терминала, чтобы посмотреть, добились ли мы каких-нибудь улучшений.

Шаг № 2: Обновите конфигурации

Итак, мы смогли срезать около 2,5 минут от времени сборки, но это все еще недостаточно хорошо. Изучив логи сборки в терминале, я наткнулся на одну строку, которая нас заинтересует:

Gradle может отключить инкрементную компиляцию, так как следующие процессоры аннотаций не являются инкрементными: butterknife-compiler-10.1.0.jar (com.jakewharton:butterknife-compiler:10.1.0), dagger-compiler-2.9.jar (com.google.dagger:dagger-compiler:2.9).

Рассмотрите возможность установки экспериментального флага android.enableSeparateAnnotationProcessing-true в файле gradle.properties для запуска обработки аннотаций в отдельной задаче и выполнения инкрементной компиляции.)

К счастью, в версии 1.3.30 Kotlin добавлена поддержка пошаговой обработки аннотаций.

hqud rdvrv8fzj2z4fadmqbqtqc

(Инкрементная обработка аннотаций (с 1.3.30)

Начиная с версии 1.3.30, kapt поддерживает инкрементную обработку аннотаций в качестве экспериментальной функции. В настоящее время обработка аннотаций может выполняться инкрементально, только если все используемые процессоры аннотаций являются инкрементными.
Чтобы включить инкрементную обработку аннотаций, добавьте эту строку в файл gradle.properties :

Обратите внимание, что инкрементная обработка аннотаций требует, чтобы инкрементная компиляция также была включена.)

apply plugin: ‘kotlin-kapt’

Затем измените все конфигурации annotationProcessor в разделе зависимостей для использования kapt. Например:

//До
annotationProcessor ‘com.google.dagger:dagger-compiler:2.9’
//После
kapt ‘com.google.dagger:dagger-compiler:2.9’

Теперь откройте файл gradle.properties, расположенный в корне вашего проекта, и добавьте следующую строку:

Давайте снова запустим сборку.

wlbgxkwt2nlgrhbf6a

Хорошо, похоже, мы еще немного продвинулись.

Шаг № 3: свойства Gradle

Мы на последнем этапе. Помните подвох, с которым мы столкнулись при обновлении версии плагина Gradle? Оказывается, более новые версии Gradle уменьшают размер используемой памяти до 512 МБ. Это сделано для того, чтобы слабые машины не расходовали слишком много памяти. У меня компьютер с 16 гигабайтами оперативной памяти, поэтому я могу позволить себе скормить около 2-3 гигов демону Gradle, но ваши цифры могут отличаться.

Откройте файл gradle.properties, расположенный в корне вашего проекта, и добавьте следующую строку. Не забудьте выбрать размер в соответствии с вашими требованиями и спецификацией компьютера.

Пока мы это делаем, давайте также включим параллельные сборки и настройку по требованию в свойствах.

Вот как выглядит мой окончательный вариант файла gradle.properties :

42g0mugmqkhqo2ok7ynl pqcf3e

Заключительные замечания

Это ни в коем случае не обширный охват всех способов оптимизации скорости сборки. Есть множество других вещей, которые я не рассмотрел в этом посте, таких как использование minSdk 21 при использовании MultiDex, предварительная индексация библиотек, отключение сжатия PNG и т. д., — это всего лишь некоторые из них.

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

Источник

Электрический блогнот

мои заметки на полях

Как ускорить Android Studio на ноутбуке

android studio rocket

Android Studio стал стандартом de facto при разработке приложений для Android. Если раньше, все было на Eclipse (а кто-то пробовал и NetBeans), то сейчас многие уходят на Android Studio. Прекрасная и удобная среда разработки. В инете много информации по ней. Если есть вопросы, как работать в Android Studio, то, где-нибудь на stackoverflow.com есть уже ответ.

Но не все так прекрасно с Android Studio. Есть одно «но» — потребляет много ресурсов. И с каждой версией требования к памяти и процессору все выше и выше. Старенький ноутбук уже не тянет (а когда-то тянул и очень хорошо тянул). Студия грузится долго, проект собирается тоже долго. Если запустить emulator Android, то ноутбук чуть ли не в swap падает (хотя раньше все нормально было).

В сети очень много советов о том, как ускорить Android Studio. Но зачастую они касаются рабочих станций, где нет проблем с оперативной памятью, быстрый жесткий диск и современный процессор. Что же делать владельцам ноутбуков? В этой статье я постараюсь собрать все рецепты, которые сделают работу в Android Studio комфортнее на слабых компьютерах, коими в большинстве своем являются ноутбуки.

Gradle

Проверьте, что установлена самая свежая версия сборщика проектов Gradle. Если давно не проверяли, то go на сайт и качайте последнюю версию: https://gradle.org/releases/.
Разработчики Gradle постоянно, что-то улучшают и в свежих версиях потребление памяти и скорость могут быть улучшены.
После того, как gradle скачан и установлен, нужно сказать Android Studio, где находится gradle. Делается — это в 2 этапа:
1) сначала говорим Android Studio, чтобы не пользовалась своим встроенным gradle wrapper’ом (галочку снимаем);
2) говорим, где находится свежескачанный gradle (галочку ставим).
Как это делается, можно посмотреть на следующей картинке:

Android Studio gradle

Gradle wrapper в Android Studio тоже хорошая вещица. В процессе сборки проекта он сам выкачивает нужную версию gradle, а потом просто ее использует. Но мы не ищем легких путей, мы сами все делаем. Хотим, чтобы все было под контролем.

Gradle Daemon

Итак, в предыдущем пункте мы выкачали gradle с официального сайта и установили самую свежую версию, попутно указав Android Studio использовать эту версию gradle. Теперь идем дальше. Чтобы ускорить начало сборки можно держать gradle в памяти.
Для этого в файл

/.gradle/gradle.properties добавляем такую строку:

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

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

Android Studio gradle daemon configuration

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

Gradle Plugin

С помощью Gradle Plugin’а Andorid Studio добавляет несколько фишек в gradle по сборке приложения под телефон на Android. Ибо сама gradle не может собрать Android app. Android Studio сама напоминает, когда обновить Gradle Plugin. Но если по каким-то причинам сборка проекта ведется из командной строки, а не из IDE, то за актуальностью Gradle Plugin нужно следить самому. Для этого в файле build.gradle (в топовом build.gradle, который расположен в корне проекта), находим строки:

и исправляем 3.0.1 на ту версию, какую вам нужно. Посмотреть самую свежую версию Gradle Plugin можно на официальном сайте разработчиков Android https://developer.android.com/studio/releases/gradle-plugin.html.

Если вы привыкли делать все из студии, то нужный файл и нужная строка представлены на следующей картинке:

Android Studio gradle plugin version

Gradle Cache

Для ускорения процесса сборки проетка Gradle может использовать результаты предыдущих сборок. Чтобы активировать эту опцию вставляем в gradle.properties следующуя строку:

Gradle Offline

При сборке Gradle смотрит в сети не появились ли новые версии библиотек, задествоанных в проекте. При медленной сети это занимает достаточно долго времемни. Поэтому отключим эту возможность. Переводим gradle в offline режим. Открываем настройки Ctrl+Alt+S, далее Build, Execution, Deployment/Gradle:

Gradle offline work

Но это не все. Открываем Compilers и добавляем ключ —offline.

Gradle offline work compiler

Instant Run

Про него слагаются легенды. Подставляя скомпилированный код находу, он позволяет отлаживать приложения на Android без глобальной персборки проекта. Это оправдано, когда проект большой в 10-ки, а то и 100-и классов. Но когда работа идет на ноутбуке над небольшим приложением, то проще пересобрать проект. А почему? А потому что Instant Run требует много памяти, а на ноуте ее нет. Поэтому отключаем:

снова идем в настройки Ctrl+Alt+S и снимаем галку с «Enable Instant Run»

Android Studio disable instant run

правда может оказаться так, что галка на Enable Instant Run серая и не дает себя снять, для этого проверьте нет ли внизу активных gradle процессов:

Gradle build runnung

дождитесь когда закончатся и попробуйте снова выключить Instant Run.

Gradle параллельная сборка

Вот здесь с осторожностью. Может, как и ускорить сборку, а может и навредить (ноутбук в swap уйдет). Поэтому проверяйте.

В настройках Ctrl+Alt+S стави галочку «Compile Independent Modules in Parallel«:

Gradle compile in parallel

Incremental Dex

С одной стороны полезная вещица, позволяет ускорить сборку. С другой стороны для эффективной работы требует немало памяти. Попробуйте с ней поиграться. Находится она вот здесь в настройках проекта (F4):

Incremental

Java Memory

Выделяем доступную память для виртуальной машины Java. По уомлчанию там стоит достаточно много, можно и убавить. Для этого через «Help/Edit Custom VM Options» открываем конфигурационный файл и правим Xms и Xmx.

Это означает, что для JVM мы выделяем 256Mb на старте и ограничиваем максимальное потребеление памяти 512-ю Mb.
Android studio java memory

Virtual Device Memory

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

Android studio virtual machine memory

RAM =5 12Mb в самый раз
Можно снять галку с «Multi-Core CPU»

File Tabs

Постарайтесь не открывать одновременно много файлов:
Android studio opened tabs

Antivirus Software

Добавьте папку с проектами Android Studio (чаще всего StudioProjects) в список исключений антивируса или Windows Defender.

Заключение

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

Источник

Понравилась статья? Поделить с друзьями:
Добавить комментарий
  • Как сделать успешный бизнес на ритуальных услугах
  • Выездной кейтеринг в России
  • Риски бизнеса: без чего не обойтись на пути к успеху
  • android studio обновление приложения без google play
  • android studio не запускается приложение на эмуляторе