Работа с изображениями может быстро привести к проблемам с производительностью, если не проявлять осторожность. Даже небольшое изображение в сжатом формате, таком как JPG или PNG, может превратиться в большой растровый файл при декодировании для отображения. Если вы неэффективно используете графику, могут возникнуть проблемы с памятью, что негативно скажется на производительности вашего приложения и других приложений на устройстве. Следуйте этим рекомендациям, чтобы обеспечить оптимальную производительность вашего приложения.
Используйте библиотеки для загрузки изображений.
Вы можете повысить эффективность своего приложения, используя библиотеки для загрузки изображений, такие как Coil (для проектов, ориентированных на Kotlin) или Glide (для проектов на Java). Эти библиотеки сокращают потребление памяти приложением за счет кэширования изображений, изменения размера графики при необходимости и повторного использования графических объектов.
При необходимости изменяйте размер изображений.
Убедитесь, что используете подходящий размер изображения для ваших нужд. Например, никогда не следует загружать большое изображение в виде маленькой миниатюры. Вместо этого используйте такой метод, как inSampleSize для загрузки измененной версии изображения.
Библиотеки для загрузки изображений, такие как Coil и Glide, автоматически выполняют передискретизацию по умолчанию. Вы можете настроить их стратегии понижения разрешения, используя ImageLoader (для Coil) или DownsampleStrategy (для Glide).
Предоставьте альтернативные ресурсы для экранов разных размеров.
Если вы поставляете изображения вместе с приложением, рассмотрите возможность предоставления изображений разных размеров для разных разрешений устройств. Это поможет уменьшить размер загружаемого приложения на устройствах и повысить производительность, поскольку на устройствах с более низким разрешением будет загружаться изображение с более низким разрешением. Для получения дополнительной информации о предоставлении альтернативных растровых изображений для разных размеров устройств ознакомьтесь с документацией по альтернативным растровым изображениям .
Не приклеивайте прокладку напрямую.
Иногда может потребоваться добавить отступы к изображению. Например, вам может понадобиться, чтобы изображение было окружено прозрачной рамкой для эффекта «letterboxing» (черных полос по краям). В таких ситуациях не следует добавлять отступы непосредственно к изображению, изменяя его размеры. Вместо этого оставьте размеры изображения как есть и отрегулируйте его положение на экране с помощью InsetDrawable . В качестве альтернативы, вы можете добавить отступы в Composable или View, содержащий изображение.
Выберите правильный формат пикселей.
Сбалансируйте использование памяти и качество, выбрав правильный формат пикселей. Используйте RGB_565 если прозрачность не требуется; этот формат использует вдвое меньше памяти, чем формат ARGB_8888 по умолчанию.
В Glide это можно настроить с помощью DecodeFormat . В Coil можно использовать свойство bitmapConfig .
По возможности используйте векторы.
Для изображений, состоящих из геометрических фигур, векторная графика значительно меньше растрового изображения и плавно масштабируется при любой плотности пикселей. При необходимости используйте такие элементы, как ShapeDrawable для представления графики.
По возможности, используйте и освобождайте растровые изображения повторно.
Большие графические файлы могут занимать много памяти. Чтобы уменьшить их влияние, следует по возможности освобождать или повторно использовать графические объекты.
Если вы используете библиотеку для загрузки изображений, убедитесь, что вы освобождаете растровые изображения в управляемом пуле библиотеки, когда они вам больше не нужны. Библиотека сможет повторно использовать объекты при необходимости и сохранит буфер памяти, доступный для будущих нужд.
При ручном управлении графикой следует освобождать растровые изображения после завершения работы с ними, вызывая метод Bitmap.recycle и немедленно удаляя ссылку на Bitmap , вместо того чтобы полагаться на сборку мусора.
Другие советы и рекомендации
В этом разделе перечислены еще несколько способов улучшить производительность вашего приложения при обработке графики.
Не упаковывайте большие изображения вместе с файлами AAB/APK.
Одной из главных причин большого размера загружаемых приложений являются графические файлы, упакованные в AAB- или APK-архивы. Используйте инструмент анализа APK , чтобы убедиться, что вы не упаковываете файлы изображений большего размера, чем необходимо. Уменьшите размер файлов или рассмотрите возможность размещения изображений на сервере и загрузки их только при необходимости.
Найти избыточные растровые изображения
Если у вас несколько копий одного и того же изображения, это приводит к нерациональному использованию памяти. Вы можете использовать профилировщик Android Studio для выявления избыточных графических элементов. Используйте анализатор дампа кучи , чтобы создать дамп кучи, и отфильтруйте результаты, выбрав параметр « дублирующиеся растровые изображения» .
При использовании ImageBitmap вызовите метод prepareToDraw перед началом отрисовки.
При использовании ImageBitmap для начала процесса загрузки текстуры на графический процессор вызовите ImageBitmap#prepareToDraw() перед фактической отрисовкой. Это помогает графическому процессору подготовить текстуру и повысить производительность отображения изображения на экране. Большинство библиотек для загрузки изображений уже выполняют эту оптимизацию, но если вы работаете с классом ImageBitmap самостоятельно, это следует учитывать.
Вместо Painter лучше передавать в качестве параметров объект DrawableRes Int или URL.
Из-за сложностей работы с изображениями (например, написание функции equals для Bitmaps потребовало бы больших вычислительных затрат), API Painter явно не помечен как стабильный с помощью аннотации @Stable . Нестабильные классы могут привести к ненужным перекомпозициям, поскольку компилятору будет сложно определить, изменились ли данные.
Поэтому мы рекомендуем передавать в качестве параметров вашего составного объекта URL-адрес или идентификатор ресурса изображения, а не объект Painter .
// Prefer this:
@Composable
fun MyImage(url: String) {
}
// Over this:
@Composable
fun MyImage(painter: Painter) {
}
Рекомендуем вам
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- ImageBitmap против ImageVector {:#bitmap-vs-vector}
- Сохранение состояния пользовательского интерфейса в Compose
- Фазы композиции Jetpack