English version - "Universal Image Loader. Part 1 - Introduction"
При разработке приложений под Android довольно часто можно столкнуться с задачей отображения некоего графического контента из интернета. Поэтому снова и снова приходится обеспечивать загрузку изображений из сети, их обработку и отображение в условиях ограниченности оперативной памяти. И несмотря на однородность задачи каждый новый проект накладывает на задачу свои специфические требования: возможно нужно организовать кэширование загруженных картинок; если картинки довольно большие, то необходимо обеспечить эффективную работу с памятью для предотвращения злополучной ошибки OutOfMemoryError; возможно во время загрузки изображения нужно показывать картинку-заглушку; а может одну и ту же картинку надо будет отображать в разных размерных вариациях; и т.д. В результате тратятся время и ресурсы на адаптацию программного кода под специфические нужды. Именно данная проблематика и подтолкнула меня к созданию библиотеки с открытым исходным кодом - Universal Image Loader, целью которой является универсализация решения вышеописанной задачи в виде гибкого и конфигурируемого инструмента.
На данный момент библиотеку можно использовать повсеместно, где надо загрузить и отобразить (и возможно ещё закэшировать) картинку из интернета или из файловой системы смартфона. Классические примеры возможности применения ImageLoader'а - это списки, таблицы, галереи, где необходимо отображать изображения из сети.
Главные фишки ImageLoader'а:
Глобальные настройки:
Возможностей конфигурирования достаточно, но это не тот случай, наподобие "главного принципа UNIX": "Вы можете сконфигурировать ВСЁ. И вы БУДЕТЕ конфигурировать все." :) В случае ImageLoader'а, вы можете настраивать все, но это отнюдь не обязательно: конфигурация по умолчанию всегда доступна и подходит для большинства случаев.
Особенности реализации
Немного слов о структуре проекта. Каждая задача на загрузку и отображение картинки (а это, забегая вперед, вызов ImageLoader.displayImage(imageView, imageUrl)) выполняется в отдельном потоке, кроме случаев, если картинка находится в кэше в памяти - тогда она просто сразу отображается. Существует отдельная очередь потоков, куда попадают задачи, если нужная картинка закэширована на файловой системе. Если же нужной картинки нет в кэше, то задача-поток попадает в пул потоков. Т.о. быстрому отображению закэшированных картинок ничего не препятствует.
Алгоритм обработки задачи упрощенно представлен на схеме:
Можно условно выделить основные действующие лица в проекте:
В следующей части Я расскажу непосредственно о Universal Image Loader API, а также дам некоторые советы и рекомендации по использованию библиотеки.
Следующие статьи:
Исходники проекта доступны здесь.
При разработке приложений под Android довольно часто можно столкнуться с задачей отображения некоего графического контента из интернета. Поэтому снова и снова приходится обеспечивать загрузку изображений из сети, их обработку и отображение в условиях ограниченности оперативной памяти. И несмотря на однородность задачи каждый новый проект накладывает на задачу свои специфические требования: возможно нужно организовать кэширование загруженных картинок; если картинки довольно большие, то необходимо обеспечить эффективную работу с памятью для предотвращения злополучной ошибки OutOfMemoryError; возможно во время загрузки изображения нужно показывать картинку-заглушку; а может одну и ту же картинку надо будет отображать в разных размерных вариациях; и т.д. В результате тратятся время и ресурсы на адаптацию программного кода под специфические нужды. Именно данная проблематика и подтолкнула меня к созданию библиотеки с открытым исходным кодом - Universal Image Loader, целью которой является универсализация решения вышеописанной задачи в виде гибкого и конфигурируемого инструмента.
На данный момент библиотеку можно использовать повсеместно, где надо загрузить и отобразить (и возможно ещё закэшировать) картинку из интернета или из файловой системы смартфона. Классические примеры возможности применения ImageLoader'а - это списки, таблицы, галереи, где необходимо отображать изображения из сети.
Главные фишки ImageLoader'а:
- асинхронная загрузка и отображение изображений из интернета или с SD-карты;
- возможность кэширования загруженных картинок в памяти и/или на файловой системе устройства;
- возможность отслеживания процесса загрузки посредством "слушателей"
- эффективная работа с памятью при кэшировании картинок в памяти;
- широкие возможности настройки инструмента под свои нужды.
Глобальные настройки:
- максимальный размер кэшируемых в памяти картинок;
- тайм-аут для установки соединения и загрузки картинки;
- максимальное количество потоков для загрузки изображений, работающих одновременно;
- приоритет потоков по загрузке и отображению картинок;
- программная реализация дискового кэша (можно выбрать одну из готовых реализаций или создать свою собственную);
- программная реализация кэша в памяти (можно выбрать одну из готовых реализаций или создать свою собственную);
- опции загрузки изображения по умолчанию
- отображать ли картинку-"заглушку" в ImageView, пока реальная картинка грузится? (если да, то нужно указать эту "заглушку");
- отображать ли какую-либо картинку в ImageView, если URL картинки был передан пустым? (если да, то нужно указать эту картинку);
- кэшировать ли загруженную картинку в памяти?
- кэшировать ли загруженную картинку на файловой системе?
- тип декодирования изображения (максимально быстрый или максимально экономный для памяти).
Возможностей конфигурирования достаточно, но это не тот случай, наподобие "главного принципа UNIX": "Вы можете сконфигурировать ВСЁ. И вы БУДЕТЕ конфигурировать все." :) В случае ImageLoader'а, вы можете настраивать все, но это отнюдь не обязательно: конфигурация по умолчанию всегда доступна и подходит для большинства случаев.
Особенности реализации
Немного слов о структуре проекта. Каждая задача на загрузку и отображение картинки (а это, забегая вперед, вызов ImageLoader.displayImage(imageView, imageUrl)) выполняется в отдельном потоке, кроме случаев, если картинка находится в кэше в памяти - тогда она просто сразу отображается. Существует отдельная очередь потоков, куда попадают задачи, если нужная картинка закэширована на файловой системе. Если же нужной картинки нет в кэше, то задача-поток попадает в пул потоков. Т.о. быстрому отображению закэшированных картинок ничего не препятствует.
Алгоритм обработки задачи упрощенно представлен на схеме:
Можно условно выделить основные действующие лица в проекте:
- вышеупомянутые очередь и пул потоков;
- кэш в памяти;
- дисковый кэш;
- декодер изображений, который перегоняет файлы картинок в объекты Bitmap.
Следующие статьи:
Исходники проекта доступны здесь.


Здравствуйте Сергей! Как с Вами можно связаться? есть вопросы. Спасибо
ReplyDeleteЗдравствуйте. На GitHub есть мой email - вот здесь
DeleteМолодьцы! Еще не юзал, но по статьям это то, что мне нужно.
ReplyDeleteСпасибо. Хорошая библиотека. Не подскажите каким образом можно сделать автоматическое слайдшоу? В каком направлении "копать"?
ReplyDeleteViewPager и Timer вам в руки.
DeleteСпасибо. Я к этому же и пришел))
ReplyDeleteПытаюсь использовать вместе с facebook api и выдает гору ошибок, может подскажете в чем моя ошибка?
ReplyDeleteИзвините, но что-то меня подводят мои экстрасенсорные способности в последнее время. Так что не смогу помочь.
DeleteПодскажите, а как можно масштабировать изображение? Дело в том, что при загрузки, оно становится меньше размера экрана и находится по середине. Изображение находится во внутренней памяти телефона, когда просматриваю стандартными средствами android - изображение на весь экран.
ReplyDeleteUIL не предоставляет функциональность масштабирования. Для этого вам нужно дополнительно использовать другие библиотеки (PhotoView, ImageViewTouch, gesture-image-view, ...). Также надо будет указать UIL, чтобы он не уменьшал картинки при декодировании: в опциях .imageScaleType(ImageScaleType.NONE).
DeleteЗдравствуйте, отличная библиотека, спасибо! А не подскажите как можно добавить функциональность double-click zoom?
ReplyDeleteДля этого надо использовать сторонние библиотеки: PhotoView, ImageViewTouch, gesture-image-view,...
Deletehttp://stackoverflow.com/questions/13398288/image-zoom-issue-with-universal-image-loader-and-view-pager
Отличная библиотека, спасибо! а можно URI с Drawable использовать?
ReplyDeleteМожно, но не нужно. https://github.com/nostra13/Android-Universal-Image-Loader#acceptable-uris-examples
DeleteДобрый день, огромное спасибо за библиотеку!
ReplyDeleteВопрос: предпочтительнее изображения использовать из assets нежели из drawable я так понимаю ?
Добрый. Да, лучше. А почему не использовать ImageView.setImageResource(...)?
DeleteИ как можно сделать донат, не юзая пэйпал ? )
ReplyDeleteWebMoney.
DeleteГде не искал, не нашел самого просто примера : как отобразить картинку из урла в ImageView.. помогите пожалуйста !
ReplyDeleteВсе круто.. я был пьян и было поздно.. Спасибо Вам за прекрасный труд !
Delete