Хабрахабр

[Из песочницы] OutOfMemory и использование векторных изображений в Android Studio

Привет, Хабр! В данной статье, ориентированной на новичков, я бы хотел дать несколько советов по оптимизации использования приложением памяти устройства, дабы постоянно не получать OutOfMemory, а также рассмотреть использование векторных изображений в текущей актуальной версии Android Studio (3.4), так как большинство русскоязычных ресурсов по этой теме (последняя статья на Хабре про векторные изображения датируется 2015 годом) устарели, что нередко вводит начинающих разработчиков в заблуждение. Итак, приступим.

1. Используйте векторные изображения вместо растровых

Конечно, большие изображения с множеством мелких деталей не стоит переводить в вектор — это займёт столько же места, как и растр, если не больше. Однако мелкие изображения, вроде иконок и остальных деталей пользовательского интерфейса следует конвертировать в вектор в целях экономии памяти. Да и работать с векторными изображениями зачастую гораздо удобнее. А теперь, самое главное — как это сделать?

  1. Открываем Android Studio.
  2. Кликаем правой кнопкой мыши по папке drawable или её содержимому > New > Vector Asset

  3. Указываем путь к своему svg-файлу. Если ваше изображение имеет неправильную форму, то советую поставить галочку рядом с параметром Override — в противном случае картинка будет подогнана под стандартные размеры, что может исказить её пропорции.

  4. Next > Finish
  5. Готово!

Для конвертации из растра в вектор могу посоветовать отличное бесплатное приложение Inkscape. Немного о работе с ним:

  1. Открываем Inkscape.
  2. Перетаскиваем в него любой растр. В открывшемся окне выбираем параметры импорта и жмём ОК.
  3. В верхнем тулбаре, предварительно выбрав наше изображение, выбираем Контур > Векторизировать растр (Shift + Alt + B).
  4. Теперь самое главное. В новом окне ставим галочку рядом с «Убрать фон» и выбираем следующее: будет ли наше изображение цветным, и сколько нужно сделать сканирований. Нельзя забывать, что от этих двух параметров напрямую зависит размер нашего векторного файла.

    Моему лепрекону, чтобы приобрести божеский вид, по причине большего количество цветов в изображении понадобилось 30 сканирований. Больше сканирований — больше цветов, оттенков и деталей. Это довольно много, лучше делать не больше десяти и выбирать картинки попроще.

  5. Закрываем окно, нажимаем на растр и удаляем его клавишей Delete, переходим в Файл > Свойства документа (Shift + Ctrl + D), подгоняем размер страницы под содержимое.

Теперь проведём небольшой тест, доказывающий преимущество вектора в экономии памяти.
Я создал новый проект с одним-единственным ImageView, к которому применил анимацию, перемещающую его из точки А в точку Б, поочерёдно изменив изображения на растровое и векторное. Смотрим данные.

Растр

Вектор

Думаю, это достаточно убедительно. Разница почти что в два раза.

2. Увеличьте размер «кучи»

Для этого перейдите в манифест вашего проекта (app > manifests > AndroidManifest.xml) и в колонке application добавьте строку:

android:largeHeap="true"

По сути, увеличение «кучи» — это не решение проблемы OutOfMemory, а её задвигание на дальнюю полку. Вместо того, чтобы оптимизировать использование приложением памяти устройства, мы даём ему больше места. Не стоит забывать и то, что у каждого устройства свой объём памяти, как основной, так и дополнительной, выделяемой под приложение.

3. Избегайте утечек памяти

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

Handler. От себя хотел бы посоветовать библиотеку WeakHandler, разработанной компанией Badoo, и призванной устранить утечки памяти, связанные с неправильным использованием android.os. Для использования данной библиотеки добавьте в свой gradle-файл (Gradle Scripts > build.gradle (Module:app)) в колонку dependencies строку:

compile 'com.badoo.mobile:android-weak-handler:1.1'

а в Java-файл:

private WeakHandler mHandler; protected void onCreate(Bundle savedInstanceState) private void onClick(View view) { mHandler.postDelayed(new Runnable() { view.setVisibility(View.INVISIBLE); }, 5000); }

И не забудьте импортировать сам WeakHandler, если студия не сделала это автоматически.

4. Избегайте больших покадровых анимаций

Покадровая анимация в Android Studio — штука удобная, но далеко не самая экономичная. При использовании в ней большого количества изображений, вы непременно получите OutOfMemory.

Эта библиотека упрощает работу c gif, а также потребляет гораздо меньше памяти, чем покадровые анимации Android Studio. Но, если уж вам это очень понадобилось, лучше используйте gif-изображение вместе с библиотекой Android Gif Drawable. Для использования данной библиотеки добавьте в свой gradle-файл (Gradle Scripts > build.gradle (Module:app)) в колонку dependencies строку:

implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.16'

и в свой второй gradle-файл (Gradle Scripts > build.gradle(Modue:«название вашего приложения»)) в колонки buildscript и allproject строку:

mavenCentral()

а в Java-файл:

GifDrawable gifFromResource = new GifDrawable( getResources(), R.drawable.имя_файла );
gifFromResource.start();

Для отключения gif вместо start() пишем stop(). Также не забывайте сжать gif-ки, это сэкономит ещё больше места.

Спасибо. Надеюсь, что моя статья была вам полезна.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть