- кэширование в памяти
- кэширование на файловой системе (память телефона или SD-карта)
В текущей версии используется кэш Bitmap'ов, контролирующий свой размер. Это было реализовано посредством введения дополнительного «жесткого» списка, где хранились «сильные» ссылки на Bitmap'ы из softMap'ы. Как только размер кэша превышает допустимый лимит, «самые старые» объекты удаляются из «жесткого списка», тем самым теряя сильную ссылку. Слабая ссылка все ещё сохраняется в softMap'e, но там Bitmap уже полностью во власти Garbage Collector'a.При кэшировании на файловой системе файлы именуются как imageUrl.hashCode() и в дальнейшем по такому же принципу проводится поиск в кэше.Рассмотрим самый полнофункциональный метод ImageLoader'а — это:public abstract class Cache<K, V> { protected final Map<K, Reference<V>> softMap = new HashMap<K, Reference<V>>(); public V get(K key) { if (softMap.containsKey(key)) { Reference<V> reference = softMap.get(key); return reference.get(); } else { return null; } } public void put(K key, V value) { softMap.put(key, createReference(value)); } public void clear() { softMap.clear(); } protected abstract Reference<V> createReference(V value); }
Параметры imageUrl и imageView, Я думаю, вопросов не вызовут.Класс DisplayImageOptions предназначен для настройки процесса загрузки, кэширования и отображения картинки. С помощью него можно указать:void displayImage(String imageUrl, ImageView imageView, DisplayImageOptions options, ImageLoadingListener listener)
- надо ли отображать картинку-заглушку в ImageView, пока загружается реальная картинка, и какую именно заглушку отображать;
- надо ли кэшировать загруженную картинку в памяти;
- надо ли кэшировать загруженную картинку на файловой системе.
Но если текущая картинка присутствует в кэше в памяти, то listener не будет бросать события. События бросаются на UI-потоке, так что можно со спокойной душой трогать UI в listener'e.Итак, пример использования ImageLoader'a:public interface ImageLoadingListener { void onLoadingStarted(); void onLoadingComplete(); }
Сильно распространяться про сам механизм работы ImageLoader'а не буду. Скажу только пару вещей:ImageLoader imageLoader = ImageLoader.getInstance(context); DisplayImageOptions options = new DisplayImageOptions.Builder() .showStubImage(R.drawable.stub_image) .cacheInMemory() .cacheOnDisc() .build(); imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() { @Override public void onLoadingStarted() { spinner.show(); } @Override public void onLoadingComplete() { spinner.hide(); } });
- задания на отображение картинки кладутся в очередь: если картинка уже есть в кэше на файловой системе, задание попадает на начало очереди, если нет — в конец. Задания выполняются с начала очереди, тем самым отображая в первую очередь закэшированные картинки; (UPD: После введения многопоточного механизма отображения картинок данная логика была упразднена. Теперь загрузкой закэшированных и незакэшированный изображений занимаются два разных пула потоков: для закэшированных — однопоточный, для остальных — многопоточный)
- в кэше в памяти хранятся не полноразмерные Bitmap'ы, а размера не менее того, который нужен для отображения в ImageView. Этот размер вычисляется, исходя из атрибутов maxWidth и maxHeight, layout_width и layout_height, размеров экрана аппарата (размер исходной картинки уменьшается на степень двойки, в соответствии с рекомендациями по декодированию изображений).
- т.к. в первую очередь ImageLoader предназначается для отображения картинок в списке, а в списках, как правило, хорошим тоном являтся переиспользование View, то и ImageLoader отслеживает такие ситуации, сохраняя загружаемый URL картинки в Tag ImageView с собственным ключом.
UPD (19.12.2011): В инструмент были внесены некторые существенные изменения, подробно о них и о проекте в целом можно прочитать здесь.
UPD (23.02.2012): Была сделана куча изменений и улучшений (в т.ч. многопоточность, внешнее конфигурирование). Но основное API в принципе все то же. Теперь инструмент доступен в качетве jar-ки. Введена версионность.
UPD (11.03.2012): Написал подробное руководство по использованию библиотеки:

