March 11, 2012

#6 - Universal Image Loader. Часть 3 - Использование [RU+EN]

English version - "Universal Image Loader. Part 3 - Usage"

Предыдущие статьи:
    В прошлой статье мы проинициализировали ImageLoader конфигурацией и теперь он готов к непосредственному использованию по назначению.
    Для этого он имеет 4 перегруженных метода:
void displayImage(String url, ImageView view)
void displayImage(String url, ImageView view, DisplayImageOptions options)
void displayImage(String url, ImageView view, ImageLoadingListener listener)
void displayImage(String url, ImageView view, DisplayImageOptions options, ImageLoadingListener listener)

    Первый вариант - все просто: говорим из какого URL-а загрузить картинку и в какой ImageView отобразить. Опции отображения (DisplayImageOptions) в этом случае будут взяты из конфигурации (defaultDisplayImageOptions(...)).
    Второй вариант: вот мы уже можем определить отдельные опции для конкретной задачи. Приведем сначала примерчик создания своих опций:
DisplayImageOptions options = new DisplayImageOptions.Builder()
    .showStubImage(R.drawable.stub_image)
    .showImageForEmptyUrl(R.drawable.image_for_empty_url)
    .resetViewBeforeLoading()
    .cacheInMemory()
    .cacheOnDisc()
    .decodingType(ImageScaleType.EXACT)
    .build();
    Да, опять Builder. Как говорилось в первой статье, с помощью DisplayImageOptions мы можем указать:
  • надо ли отображать картинку-заглушку в ImageView, пока загружается реальная картинка, и какую именно заглушку отображать;
  • надо ли отображать какую-либо картинку в ImageView, если URL картинки был передан пустым (null), и какую именно картинку отображать;  
  • "обнулять" ли ImageView перед началом загрузки; 
  • надо ли кэшировать загруженную картинку в памяти;
  • надо ли кэшировать загруженную картинку на файловой системе.
  • декодировать изображение максимально быстро (ImageScaleType.POWER_OF_2) или максимально экономно для оперативной памяти (ImageScaleType.EXACT).
    Так вот, мы можем передавать эти опции при каждом вызове метода displayImage(), а можем указать дефолтные в конфигурации для инициализации, и они будут использоваться во всех случаях, когда опции не были явно переданы при вызове метода.
    Третий вариант: в дополнение ко всему вы можете "прослушивать" процесс загрузки и отображения картинки с помощью интерфейса ImageLoadingListener:
public interface ImageLoadingListener {
    void onLoadingStarted();
    void onLoadingFailed();
    void onLoadingComplete();
    void onLoadingCancelled();
}
    Ну а четвертый вариант - самый мощный: можете и опции определить, и "слушать" процесс.

    Советы и рекомендации
  1. Для того, чтобы ImageLoader смог выполнить свое предназначение, ему необходимо передать корректные параметры. И речь не столько о URL картинки, сколько об ImageView. Если вы создаете объект ImageView в коде (а не с помощью LayoutInflater), то в передавайте конструктор текущий Activity, а не контекст приложения:
  2. ImageView imageView = new ImageView(getApplicationContext()); // НЕ ПРАВИЛЬНО!
    
    ImageView imageView = new ImageView(MyActivity.this); // правильно
    ImageView imageView = new ImageView(getActivity()); // правильно (для Fragment'ов)
    
  3. Параметры maxImageWidthForMemoryCache(...) и maxImageHeightForMemoryCache(...) стоит настраивать в конфигурации только если вы хотите загружать в ImageView картинки размера, превышающего размеры экрана устройства (например для последующего увеличения). Во всех остальных случаях этого делать не нужно: эти параметры по умолчанию учитывают размеры экрана, что позволяет экономить память при работе с Bitmap'ами.
  4. Устанавливайте размер пула потоков в конфигурации с умом: большой размер пула (> 10) позволит работать множеству потоков одновременно, что может сильно сказаться на отзывчивости UI. Но это можно поправить установкой более низкого приоритета для потоков: чем ниже приоритет, тем отзывчивей UI во время работы ImageLoader'а, но тем долльше грузятся картинки. Отзывчивость UI крайне важна для списков (плавная прокрутка), поэтому стоит поиграться с натройкой параметров threadPoolSize(...) и threadPriority(...) для подбора оптимальной конфигурации для вашего приложения.
  5. Настройки memoryCacheSize(...) и memoryCache(...) перекрывают друг друга, используйте только одну из них для одного объекта конфигурации.
  6. Настройки discCacheSize(...), discCacheFileCount(...) и discCache(...) перекрывают друг друга, используйте только одну из них для одного объекта конфигурации. 
  7. Если при использовании ImageLoader'а в приложении вы всегда (или почти всегда) передаете в метод displayImage(...) одни и те же опции загрузки (DisplayImageOptions), то тогда разумным решением будет задать данные опции в конфигурации ImageLoader в качестве опций по умолчанию (метод defaultDisplayImageOptions(...)). Тогда данные опции не обязательно будет каждый раз указывать при вызове displayImage(...), т.к. если в метод явно не переданы опции, то для данной задачи будут использоваться дефолтные опции.
  8. Большой разницы в скорости между типами декодирования POWER_OF_2 и EXACT нет, но рекомендуется использовать POWER_OF_2 для разного рода списков (где нужно отображать много картинок небольшого размера), а  EXACT для галерей (когда нужно отображать картинки в больших размерах).
    На этом, пожалуй, Я завершу свой затянувшийся рассказ об Universal Image Loader'е.
    Иходники проекта по прежнему доступны на GitHub.  

178 comments:

  1. Насколько я понял, в новой версии убрали DecodingType.

    ReplyDelete
    Replies
    1. Точнее переименовали в ImageScaleType.
      FAST -> POWER_OF_2
      MEMORY_SAVING -> EXACT

      Delete
  2. Вместо картинки пришёл html (или другой мусор). Это возможно отловить? В логах вижу SkImageDecoder::Factory returned null, но как отловить ошибку декодирования я не вижу.

    ReplyDelete
    Replies
    1. С помощью слушателя:

      imageLoader.displayImage(imageUri, imageView, options, new SimpleImageLoadingListener() {
      @Override
      public void onLoadingFailed(FailReason failReason) {
      switch (failReason) {
      case IO_ERROR:
      // Вот сюда должен прийти callback в случае ошибки
      break;
      }
      }
      });

      Delete
    2. Не приходит callback. Ошибки при загрузке нету. Простой способ проверить -- указать в качестве адреса картинки http://ya.ru . ImageLoader пришедший html даже кеширует.

      Delete
    3. В новой версии 1.5.2 поправил этот момент. IO_ERROR должен приходить.

      Delete
  3. Как можно сделать, чтобы на диск кешировалось постоянно, а не только когда кеш памяти переполнится?

    ReplyDelete
    Replies
    1. С чего вы взяли, что на диск кэшируется только после переполнения памяти?

      Delete
    2. По логам видно, кроме того если после загрузки изображений отключить связь и убить приложение, то не все картинки сохранятся на карточке.

      Всё, я уже разобрался. Надо было .cacheOnDisk указывать перед .cacheInMemory.

      Delete
    3. Вообще-то кэширование на диске зависит только от вызванной или не вызванной .cacheOnDisk в options. Если не указано, то и кэшировать на диске не будет, даже при "переполнении памяти".

      Порядок вызова опций в options не имеет значения. Как и в конфигурации.

      Delete
  4. А нормально то, что в коде так получается что строчка : .imageScaleType(ImageScaleType.POWER_OF_2)
    выглядит так, что POWER_OF_2 зачеркнутым написанно?

    ReplyDelete
    Replies
    1. Это значит, что этот параметр устарел и его лучше не использовать (в будущем он будет удален). Всю инфу можно найти в Java доках, если они вам видны. В общем, замените POWER_OF_2 на IN_SAMPLE_POWER_OF_2.

      Delete
    2. This element neither has attached source nor attached Javadoc and hence no Javadoc could be found.
      А как можно увидеть javadoc?

      Delete
    3. Попробуйте использовать jar-ку, которая в Example проекте. Там в jar-ке сразу исходникик лежат с java-доками.

      Delete
    4. Не выходит. Она вообще не присоединяется к проекту - не читается(

      Delete
    5. universal-image-loader-1.7.0-with-src.jar

      Delete
    6. А как вы его присоединяете? И какая у вас IDE?

      Delete
    7. У меня Эклипс 4.2.0
      Добавляю через Add JARs... Я что-то не так делаю? =(

      Delete
    8. Надо jar-ки закидывать в папку libs в корне проекта. Из Build Path поудалять все ссылки на jar-ки, они должны автоматически присоединяться.

      Delete
  5. Оч. здорово получилось, по-моему!
    Огромный выбор настроек, меняющих поведение ImageLoader'a + возможность все запустить вообще без настроек.
    Прикрутил подгрузку картинок к приложению буквально с первого запуска (а до этого часа полтора читал туториалы и просматривал структуру классов :)).

    ReplyDelete
    Replies
    1. Все бы так читали туториалы сначала... :) Спасибо.

      Delete
  6. Здравствуйте!
    У меня проблема со ссылками вида:
    http://tonkosti.ru/images/5/54/Caretta_Bar%26Disco%2C_%D0%BE%D1%82%D0%B5%D0%BB%D1%8C_Adora_Golf_Resort_%D0%91%D0%B5%D0%BB%D0%B5%D0%BA.jpg
    Мне выдается ошибка:
    libjpeg error 27 from setjmp [0 0]
    Могли бы вы подсказать как справиться?

    ReplyDelete
    Replies
    1. Здравствуйте. Какие это у вас особенные картинки. Дело не в ссылке, а в том, что андроидовский декодер не может задекодить такую картинку. Почему - не знаю.

      Delete
    2. Мне тут сказали, что CMYK формат не читается ни на каких версиях андроида =(
      http://stackoverflow.com/questions/7608507/in-android-how-to-decode-a-jpeg-in-cmyk-color-format/7634763#7634763

      Delete
  7. Hello Sergey, I've a problem with Image Loader (wich is very fine), I just want to display a local drawable from local. So I put this URL into my String array :
    public static final String[] IMAGES = new String[]{ "drawable://" + R.drawable.app_icon }

    but it doesnt work and I've a null pointer exception..

    Can you tell me how display drawable ?

    ReplyDelete
    Replies
    1. Look here - http://stackoverflow.com/questions/14098993/how-to-use-universal-image-loader-for-loading-resources-locally

      Delete
    2. yes but I don't understand why : "drawable://" + R.drawable.app_icon, // Image from drawables doesn't work... do you??

      Delete
    3. Did you set ExtendedImageDownloader to configuration?

      Delete
    4. yes I'm doing this in UILApplication.java : ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
      .threadPriority(Thread.NORM_PRIORITY - 2)
      .memoryCacheSize(2 * 1024 * 1024) // 2 Mb
      .denyCacheImageMultipleSizesInMemory()
      .discCacheFileNameGenerator(new Md5FileNameGenerator())
      .imageDownloader(new ExtendedImageDownloader(getApplicationContext()))
      .tasksProcessingOrder(QueueProcessingType.LIFO)
      .enableLogging() // Not necessary in common
      .build();

      So..

      Delete
  8. Anonymous12/2/13 14:49

    ...Если открыть изображение, пролистать его в любую сторону, то при повороте экрана изображение не сохраняется. А отображается повернутый рисунок, который открывался раньше, словно пролистывания и не было... Где это можно подправить?

    ReplyDelete
  9. Anonymous12/2/13 17:04

    а... понял.. У Вас в BaseActivity идет переопределение onSaveInstanceState

    ReplyDelete
  10. Скажите, а можно как либо сохранить картинку в файловый кэш?
    Допустим я сделал фотку, хочу её сразу поместить в файловый кэш, можно в принципе сохранить её по пути cacheDir который я задаю при инициализаци ImageLoader-а и прогонять имя теме же NameGenerator-ом, но нет ли более простого решения.

    ReplyDelete
  11. Каким образом у Вас в библиотеке обрабатывается ошибка, возникающая в случае, если в дисковом кэше закончилось место или если дисковый кэш располагался на SD-карте и карта была отключена от девайса?
    Если не обрабатывается, тот каким образом есть возможность обработать, а лучше предупредить данные ошибки из вне?
    Данные ошибки при использования дискового кэша на SD-карте приводят к тому, что картинки перестают загружаться, а хотелось бы, чтобы библиотека просто продолжала загружать картинки без использования кэша.

    ReplyDelete
    Replies
    1. Случаи такие не обрабатываются (что не есть хорошо), занес их в планы.
      На данный момент, чтобы хэндлить случаи отключения SD краты, надо сделать свой кэш (можно унаследоваться от какого-нибудь существующего, и засетить его в конфиг), в котором будет метод типа setCacheDir(File dir). Далее в случае отключения карты - сетить другую папку (StorageUtil.getCacheDirectory() пойдет).

      Следить за тем, не закончилось ли место на карте, тоже придется самому, и чистить кэш в этом случае.

      Над решением проблемы буду думать, но скоро ли будет - не знаю.

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

    ReplyDelete
    Replies
    1. Если вы использовали кэширование на диске, то оно уже сохранено в кэше. Остается только скопировать его куда надо. Посмотрите в сторону DiscCacheUtil.

      Delete
  13. Здраствуйте, подскажите есть ли возможность обновить изображение в кеше. скажем загрузили картинку, она попала в кеш, затем эта картинка поменялась, скажем ориентацию например поменяла. Снова пытаемся загрузить ее, но ImageLoader берет все старую картинку из кеша( как ее обновить в кеше?

    ReplyDelete
    Replies
    1. Чтобы форсировать обновление картинки, надо удалить ее из кэшей сначала. Используйте MemoryCacheUtil и DiscCacheUtil для этого. А также посмотрите в сторону LimitedAgeMemoryCache и LimitedAgeDiscCache, которые через указанное время сами удаляют картинку из кэша.
      Учтите, что UIL сначала смотрит в кэш в памяти, потом в дисковый кэш, и потом загружает картинку из сети, если ее не нашлось в кэшах.
      Кэши конфигурятся в конфигурации, а включаются в DisplayImageOptions.

      Delete
  14. Anonymous15/4/13 15:59

    Здаствуйте, подскажите возможно ли получить изображение как BitMap, а не сразу отображать его в ImageView? Дело в том что мне нужно отобразить изображение в ImageView как Background...

    ReplyDelete
    Replies
    1. ImageSize targetSize = ImageSizeUtils.defineTargetSizeForView(imageView, 0 /* or maxImageWidth */, 0 /* or maxImageHeight */)
      ImageLoader.loadImage(..., targetSize, listener)

      В листенере в onLoadingComplete(...) получаете готовую битмапку.

      Delete
  15. Anonymous23/4/13 12:35

    Сергей, спасибо за библиотеку. Есть одна проблема. Не могу правильно настроить размер пула потоков. Список подлагивает. по разному пытался настроить.. но как-то без изменений

    ReplyDelete
    Replies
    1. Одна настройка размера пула не спасет, если пролемы в другом. Обязательно для списков используйте переиспользование вьюх. Вопросы вы можете задавать здесь - http://stackoverflow.com/questions/tagged/universal-image-loader

      Delete
    2. Anonymous23/4/13 14:47

      ViewHolder, ViewStub... Всё имеется. Если закоментировать displayImage то список не лагает.

      config такой
      new ImageLoaderConfiguration.Builder(
      getApplicationContext())
      .threadPoolSize(20).threadPriority(1)

      .defaultDisplayImageOptions(optionsList)
      .memoryCache(new LruMemoryCache(150 * 1024 * 1024)).build();


      DisplayImageOptions optionsList = new DisplayImageOptions.Builder()
      .showStubImage(R.drawable.placeholder)
      .showImageOnFail(R.drawable.placeholder)
      .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
      .showImageForEmptyUri(R.drawable.placeholder).cacheInMemory()
      .cacheOnDisc().build();

      Delete
    3. Anonymous23/4/13 14:48

      .threadPoolSize(20).threadPriority(1) этого нету) уже удалил

      Delete
    4. Размер кэша в памяти - 150 метров? Это вы зря. Максимум 16.
      Повторюсь - всевопросы на StackOverFlow с подробным описанием и примерами кода.

      Delete
  16. Как можно использовать несколько ImageLoaderConfiguration?
    Мне надо один для списков.. что бы указывать размер высоты и ширины кеша в диск.. а второй для галерей, где надо кешировать полный размер

    ReplyDelete
    Replies
    1. Если только создать два инстанса ImageLoader'а. Нужно создать свой класс и унаследовать ImageLoader.

      Delete
    2. Спасибо за совет.

      Delete
  17. Anonymous1/5/13 12:01

    Привет. Почему иногда большие фотки обрезаются при загрузки?

    ReplyDelete
  18. Anonymous28/5/13 10:18

    Добрый день. У меня проблемы в использовании библиотеки с маркерами в гугл-картах. Отображается предзагрузочное изображение, а чтобы увидеть финальное, надо еще раз кликнуть по маркеру.
    Я пробовала в onLoadingComplete вызывать invalidate, но не помогает =( Не подскажете что делать?

    ReplyDelete
    Replies
    1. Не подскажу. Но может посмотрите ответ здесь:
      http://stackoverflow.com/questions/16144341/android-googlemap-2-update-information-dynamically-in-infowindow-with-imageview
      http://stackoverflow.com/questions/15503266/dynamic-contents-in-maps-v2-infowindow

      Delete
    2. Anonymous28/5/13 11:26

      Спасибо)

      Delete
  19. Сергей. Доброго времени суток) Сразу скажу, что я только начинаю писать приложения на андроиде. И у меня возник вопрос: как, прямо из приложения, можно сделать так, чтобы установить понравившуюся картинку на рабочий стол? Спасибо.

    ReplyDelete
    Replies
    1. Добрый день. Я не знаю)) UIL вам в этом не поможет.

      Delete
  20. Здравствуйте, Сергей.
    Не могу понять, как грузить картинки из дискового кеша? При отсутствии интернета они загружаются оттуда сами. Мне же надо загружать их всегда из кеша, кроме первого запуска, когда они туда загрузятся.

    ReplyDelete
    Replies
    1. Здравствуйте. Не могу понять суть вашего вопроса.

      Delete
    2. Мне нужна команда загрузки картинки из кеша.
      Сейчас загружаю картинки так:

      imageLoader.displayImage(imgUrls.get(i-1).get("image").toString(), imageView, options);

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

      Суть программы у меня в том, что есть листающиеся страницы каталога. URL картникок берется из JSON. Когда я меняю ориентацию экрана при наличии интернета, ImageLoader начинает грузить картинки из интернета, что приводит в черному экрану на 1-2 сек. Без интернет соединения переворот происходит отлично, без задержек.

      Delete
    3. ImageLoader всегда грузит картинки из кэша, если они там есть.
      Покажите свои display options.

      Delete
    4. ImageLoader imageLoader = ImageLoader.getInstance();

      ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
      .discCache(new UnlimitedDiscCache(cacheDir))
      .enableLogging()
      .build();

      imageLoader.init(config);

      DisplayImageOptions options = new DisplayImageOptions.Builder()
      .showStubImage(R.drawable.loading37)
      .cacheOnDisc()
      .build();

      Delete
    5. ImageView imageView = (ImageView) page.findViewById(R.id.imageView);

      ImageView находятся на страницах (page.xml), которые прокручиваются компонентом ViewPager.

      Delete
    6. С чего вы взяли что UIL начинает грузить картинки из интернета при повороте экрана? Из-за черного экрана? Посмотрите лучше у себя, не делаете ли вы какой-нибудь тяжелой работы на UI потоке, в onCreate() например.

      Delete
    7. Да, я был виноват. Извините за беспокойство. Надо было вчитатся в логи. Там отчетливо написано, что изображения загружены из кеша.
      Сейчас все исправил, работает :)

      Спасибо большое за такой отличный компонент.

      Delete
    8. This comment has been removed by the author.

      Delete
    9. Подскажите пожалуйста, в чем проблема с листенером? Пробую делать вот так:

      imageLoader.displayImage(imgUrls.get(i-1).get("image").toString(), imageView, options, new ImageLoadingListener(){

      @Override
      public void onLoadingStarted() {
      // TODO Auto-generated method stub

      }

      @Override
      public void onLoadingFailed() {
      // TODO Auto-generated method stub

      }

      @Override
      public void onLoadingComplete() {
      // TODO Auto-generated method stub

      }

      @Override
      public void onLoadingCancelled() {
      // TODO Auto-generated method stub

      }});

      Компилятор выдает ошибку:

      The method displayImage(String, ImageView, DisplayImageOptions, ImageLoadingListener) in the type ImageLoader is not applicable for the arguments (String, ImageView, DisplayImageOptions, new MainActivity.ImageLoadingListener(){})

      На хабре в примере использован именно такой способ...

      Delete
    10. Сигнатуры методов уже поменялись давно, статья порядком устарела. Посмотрите в Readme на GitHub.

      Delete
  21. Здравствуйте. В кэш какой? В памяти или на файловой системе?

    ReplyDelete
  22. Почти. Просто он еще создает ненужный для вас Bitmap. Но другого способа нет. Передавай маленький ImageSize в loadImage(), типа new ImageSize(2, 2), чтобы создавлись маленькие битмапки, не расходовали память.

    ReplyDelete
  23. Anonymous22/7/13 10:45

    Добрый день! Когда количество изображений в GridView превышает 30, и я делаю фото, вылетает OutOfMemoryError.
    Подскажите, пожалуйста, из-за чего это может быть и как возможно исправить? Я добавляю в onPause imageLoader.clearMemoryCache(), но всё равно не помогает.

    ReplyDelete
    Replies
    1. Добрый день. На какой версии Android?

      Delete
    2. Добрый день!

      Такая же проблема, только у меня в приложении много ListView и в каждом элементе есть картинка (75х75).

      Уж чего я только не пробовал... Очень быстро расходуется виртуальная память (буквально 100 метров за 10 мин работы)

      Кэш в память не использую, только на диск..


      В чем может быть дело? Android 2.3.6

      Delete
  24. Anonymous13/8/13 13:20

    Please answer this question -
    http://stackoverflow.com/questions/18202439/how-to-use-dynamic-drawable-instead-of-resource-in-displayimageoptions-in-univer

    ReplyDelete
  25. Anonymous15/8/13 09:59

    Прочитал все примеры использования, так и не понял как прикрутить "лоадер" к ImageView в списке на базе SimpleAdapter'а. Обычное добавление в список делаю через
    m = new HashMap();
    ...
    m.put("img", R.Drawable.img1);
    data.add(0,m);
    где data это ArrayList>

    ReplyDelete
    Replies
    1. Чтобы заюзать ImageLoader надо по-любому перегружать getView(...). Иначе никак.

      Delete
  26. Hello Sergey Tarasevich, I have this question on stack can you check it? http://stackoverflow.com/questions/18287188/detecting-the-image-size-to-be-displayed-and-use-it-by-the-lazy-loading-image Thank you.

    ReplyDelete
  27. Здравствуйте, Сергей! Отличная библиотека у вас получилась, у меня есть пара вопросов.
    Какое будет поведение при попытке загрузки gif? Вернет ли библиотека превью первый кадр?
    Как загружаются большие изображения? Например длинные 800*10000. В андройдах >4.0 отрисовка идет через opengl и отображение изображения зависит от размера текстурного буфера opengl. Есть ли идеи добавить возможность разбивать загружаемые изображения на части?
    И последний вопрос: Могу ли я получить путь к кэшированому файлу по ссылке?
    Спасибо! :)

    ReplyDelete
    Replies
    1. При попытке загрузки gif библиотека вернет первый кадр.
      Отрисока больших картинок не идет через OpenGL, картинка скейлится, как и все остальные. Есть большая вероятность, что она все равно не поместиться в памяти, или по размерным параметрам невозможно будет создать Bitmap. Идеи разбивать на части нет.
      Получить путь к кэшированому файлу по ссылке: DiscCacheUtil вам в помощь.

      Delete
  28. Здравствуйте Сергей!
    Скажите, пожалуйста, каким образом можно получить массив загруженных картинок без их отображения? Или же как загрузить и отобразить несколько картинок в галереи?
    Заранне спасибо

    ReplyDelete
    Replies
    1. Я подозреваю что можно просто проверить сколько файлов в кэше лежат например, столько и загруженных картинок.

      Delete
  29. Anonymous18/9/13 15:30

    Подскажите пожалуйста, как пофиксить OutOfMemory? использую библиотеку universal-image-loader-1.8.6-with-sources

    ReplyDelete
    Replies
    1. Все мои соображения по поводу ООМ написаны в Readme на GitHub - https://github.com/nostra13/Android-Universal-Image-Loader#useful-info
      Больше ничем не могу помочь.

      Delete
  30. Anonymous18/9/13 18:16

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

    ReplyDelete
  31. How do I get the image url link in imageview? I use Universal image loader and Added ability to download.As you can see the following codes,At that moment the displayed image imageview type URL automatically, I need to print part of file_url.I need imageview shortcut.Pleas help me.


    // File url to download
    private static String file_url = ""; <<<<<<<-----here

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Bundle bundle = getIntent().getExtras();
    imageUrls = bundle.getStringArray(Extra.RESIM);

    btnShowProgress = (Button) findViewById(R.id.btnProgressBar);

    my_image = (ImageView) findViewById(R.id.my_image);
    /**
    * Show Progress bar click event
    * */
    btnShowProgress.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
    // starting new Async Task
    new DownloadFileFromURL().execute(file_url);
    }
    });

    ReplyDelete
    Replies
    1. You can keep image URL in tag of ImageView:
      imageView.setTag(url);
      ...
      String url = (String) imageView.getTag();

      Delete
  32. Есть ли возможность в опции .showStubImage(R.drawable.***) задать анимацию из ресурсов?






    ReplyDelete
  33. так а каким образом? написала в xml-файл анимацию (list-animations), указываю ее .showStubImage(R.anim.***), но ничего не показывается, картинки грузятся но до момента отображения ничего не показывается, ни анимация, ни даже хотя бы первый кадр. сама анимация рабочая, проверила на imageview.

    ReplyDelete
    Replies
    1. Да, похоже сейчас надо стартовать анимацию вручную через листенер. Посмотрите здесь решение https://github.com/nostra13/Android-Universal-Image-Loader/issues/122

      Delete
    2. спасибо

      Delete
  34. Здравствуйте. Подскажите, какие параметры нужно установить, чтобы отображать картинку максимального качества?

    ReplyDelete
    Replies
    1. Здравствуйте.
      Нужно отключить скалирование картинки: DisplayImageOptions.imageScaleType(ImageScaleType.NONE)
      Тогда битмапка во вьюшке будет оригинального размера. Если оригинальный размер не нужен, а важно качество декодирования, то это конфигуриться через DisplayImageOptions.bitmapConfig(...). По умолчанию стоит Bitmap.Config.ARGB_8888, т.е. самое лучшее качество.

      Delete
    2. Большое спасибо.

      Delete
  35. After looking at the source of this: /universalimageloader/core/ImageLoaderEngine.java

    private final AtomicBoolean paused = new AtomicBoolean(false);
    .......

    void resume() {
    synchronized (paused) {
    paused.set(false);
    paused.notifyAll();
    }
    }
    ......

    Stop digging further into this library.

    Check it out the goal of using Atomic from concurrency package, dude.

    ReplyDelete
    Replies
    1. I understand your skepticism but this variable plays double role. This is boolean var and sync object. I can use additional variable "private Object syncObject" to implement pause/resume logic.

      But I decided re-use "paused" variable and it gives the impression of incorrect usage of AtomicBoolean.

      Delete
  36. Anonymous6/11/13 13:33

    Здравствуйте! Подскажите, пожалуйста, как правильно настроить параметры в maxImageWidthForMemoryCache(...) и maxImageHeightForMemoryCache(...) для разных по размеру устройств, чтобы можно было увеличивать картинку?

    ReplyDelete
    Replies
    1. Увеличивать картинку - в смысле "зумить"? В display options указать imageScaleType(ImageScaleType.NONE)

      Delete
    2. Anonymous6/11/13 22:17

      Да, к примеру, как Вконтакте.
      К сожалению, не помогло это. Мои настройки такие:

      DisplayImageOptions options = new DisplayImageOptions.Builder()
      .showImageOnLoading(R.drawable.no_photo_details)
      .resetViewBeforeLoading(true)
      .cacheInMemory(true)
      .cacheOnDisc(true)
      .imageScaleType(ImageScaleType.NONE)
      .build();

      File cacheDir = StorageUtils.getCacheDirectory(context);
      ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
      .memoryCacheExtraOptions(480, 800)
      .threadPoolSize(3)
      .threadPriority(Thread.NORM_PRIORITY - 1)
      .tasksProcessingOrder(QueueProcessingType.FIFO)
      .denyCacheImageMultipleSizesInMemory()
      .memoryCache(new LruMemoryCache(2 * 1024 * 1024))
      .discCache(new UnlimitedDiscCache(cacheDir))
      .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
      .defaultDisplayImageOptions(options)
      .build();

      Delete
  37. Hi Sergey,

    First of all I want THANK YOU for your work with this library.

    I want to browse folders from Android device to show to the user all pictures from it.

    The problem is that some times folder names or file names contain space character and I get ERROR ( for example this error: java.io.FileNotFoundException: /storage/emulated/0/Pictures/Sky%20Lantern.jpg: open failed: ENOENT (No such file or directory) )

    ...what should I do in this situation?

    Everything else is working fine ...only this problem I have it at this time. Any help?

    Thanx

    ReplyDelete
    Replies
    1. I found the solution ...

      String uri = fileName.getUri().toString();
      String decodedUri = Uri.decode(uri);

      ImageLoader.getInstance().displayImage(decodedUri, holder.img);

      Take care.

      Delete
  38. Сергей, спасибо большое за проделанную работу, очень полезная библиотека!

    ReplyDelete
  39. Классная библиотека, пользуюсь )))

    ReplyDelete
  40. Здравствуйте. Спасибо за библиотеку. Пытаюсь добавлять фотки в кастомный ViewGroup (без адаптера): загружаются одна - три фотки, для остальных пишет "ImageView is reused". Вот куски кода:

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
    getApplicationContext())
    .threadPoolSize(5)
    .threadPriority(Thread.MIN_PRIORITY + 2)
    .memoryCacheSize(1500000)
    .denyCacheImageMultipleSizesInMemory()
    .discCache(
    new TotalSizeLimitedDiscCache(cachDir, 20 * 1024 * 1024))
    .imageDownloader(
    new CustomBaseDownloader(getApplicationContext()))
    .build();
    ImageLoader.getInstance().init(config);

    options = new DisplayImageOptions.Builder()
    .showImageOnLoading(R.drawable.placeholder_scaled)
    .displayer(new FadeInBitmapDisplayer(500)).build();


    final ImageView icon = new ImageView(
    InventoryDetailsActivity.this);
    imageLoader.displayImage(url, icon, options);
    layout.addView(icon);

    Это как-то решается?

    ReplyDelete
    Replies
    1. Нужно бы сетить лэйаут парметры вьюхе: icon.setLayoutParams(...)
      И сначала сделать layout.addView(icon);
      а потом imageLoader.displayImage(url, icon, options);

      Вьюхи же всегда новые создаете в цикле?

      Delete
  41. Да, вьюхи всегда новые. Вот метод для вьюхи:

    private View getView(final String url) {

    // корневой контейнер
    final RelativeLayout layout = new RelativeLayout(
    InventoryDetailsActivity.this);

    layout.setLayoutParams(new GridView.LayoutParams(
    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

    layout.getViewTreeObserver().addOnGlobalLayoutListener(
    new ViewTreeObserver.OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {
    MyLog.printlog("onGlobalLayout");
    int layoutWidth = layout.getWidth();
    int layoutHeight = layout.getHeight();

    // фото объекта
    final ImageView icon = new ImageView(
    InventoryDetailsActivity.this);

    icon.setBackgroundColor(Color.BLACK);
    iconParams = new RelativeLayout.LayoutParams((int) 14
    * layoutWidth / 15,
    (int) layoutWidth * 14 / 20);

    iconParams.setMargins(0, (int) layoutWidth / 20, 0, 0);
    icon.setLayoutParams(iconParams);

    icon.setScaleType(ScaleType.FIT_CENTER);
    icon.setPadding(3, 3, 3, 3);
    //icon.setImageResource(R.drawable.placeholder_scaled);
    layout.addView(icon);
    imageLoader.displayImage(url, icon, options);

    // иконка delete
    final ImageView iconDelete = new ImageView(
    InventoryDetailsActivity.this);

    deleteIconParams = new RelativeLayout.LayoutParams(
    (int) layoutWidth / 5, (int) layoutWidth / 5);
    deleteIconParams.setMargins(layoutWidth
    - (int) layoutWidth / 5, 0, 0, 0);
    iconDelete.setLayoutParams(deleteIconParams);
    layout.addView(iconDelete);
    iconDelete.setImageResource(R.drawable.ic_del);

    // обработчик delete
    iconDelete.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {

    int index = gridview.indexOfChild((View) v
    .getParent());
    String invID = String.valueOf(inventoryDetail
    .getInventoryID());

    String pictureID = String
    .valueOf(inventoryDetail
    .getResultObjectImages()
    .get(index)
    .getInventoryPictureID());
    sendRequestToDelete(invID, pictureID, index);

    }

    });

    layout.getViewTreeObserver()
    .removeGlobalOnLayoutListener(this);

    }
    });

    return layout;

    ReplyDelete
    Replies
    1. Честно говоря, не знаю, в чем может быть проблема.

      Delete
    2. Ок, спасибо за библиотеку и за ответ.

      Delete
  42. Anonymous5/12/13 12:59

    This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Anonymous5/12/13 13:23

      This comment has been removed by the author.

      Delete
  43. Спасибо за библиотеку. Понравилось. Работает отлично. Буду читать описание, как оптимально настраивать. Скажите, а как, и можно ли настроить для просмотра большой картинки из пейджера (загружая её из кэша), увеличивая её до размеров превышающие размер экрана, как это делается в браузерах или установленных галереях.

    ReplyDelete
    Replies
    1. Функциональности зуминга в UIL нет. Для этого надо использовать другие библиотеки, типа PhotView. Чтобы зумить нормально, надо поставить ImageScaleType.NONE в опциях, т.о. в ImageView будут положены полнорамерные битмапы. Хранить их в кэше в памяти (memoryCache) не рекомендую.

      Delete
  44. спасибо за ответ, теперь понятно. да согласен в памяти хранить не стоит. Да мне именно зум и нужно реализовать. какие еще библиотеки оптимальные для зумирования есть?

    ReplyDelete
    Replies
    1. gesture-image-view, ImageViewTouch, может еще какие. Я бы в первую очередь смотрел в cторону PhotoView/.

      Delete
  45. А чем PhotoView лучше? Есть опыт использования? Или PhotoView качественнее?
    Я сейчас попробовал PhotoView вроде работает, буду разбираться дальше

    ReplyDelete
    Replies
    1. Мне кажется он качественнее, его делают проверенные люди.

      Delete
  46. Спасибо! Мне вот непонятно, если подгружать полноразмерное изображение для просмотра с зумом для всех изображений не совсем хорошо. Скорее всего при просмотре через пейджер, не все же изображения будут зумировать, то наверное лучше например выводить кликом новый ImageView в новом Activity поверх пейджера, и в котором уже тогда вывести полноразмерный битмап, который будет взаимодействовать с PhotoView со всеми прелестями зумирования?

    ReplyDelete
    Replies
    1. Это уже вам решать, как сделать.

      Delete
    2. Часто хочется услышать совет знающего человека, правильные размышления или нет, на правильном пути или понесло не в ту сторону. Может я то что писал в корне неверно, и все гораздо проще решается...

      Delete
  47. Зуминг можно сделать и в рамках пэйджера. Просто надо будет отлавливать зуминг и при увеличении отключать обработку тачей пэйджером. Т.е.pager должен игнорить приходящие в него тачи, пока зум картинки не вернется в 1. тогда юзер снова сможет листать pager, а до этого он мог скейлить и двигать саму картинку.

    ReplyDelete
    Replies
    1. Спасибо, теперь понятно. Просто пока не занимался этим вопросом, не совсем все себе представлял, то тут и с чем.

      Delete
  48. Anonymous22/1/14 04:41

    Здравствуйте!
    А можно простой пример как с помощью вашей библиотеки отобразить все изображения с определенной папки на SD карте?
    imageLoader.displayImage(imageUrl, imageView); - так я могу вставить только одну картинку ((

    ReplyDelete
    Replies
    1. Здравствуйте. Извините, но нету времени.

      Delete
  49. Сергей, ваша библиотека просто супер, спасибо большое!) Но возникла одна проблема: в вашем примере массив с URL заранее заполнен, а мне нужно пропарсить какой-либо сайт и потом уже заполнить массив ссылками на картинки. Сколько часов ломаю голову,ничего не получается...Если не трудно, помогите пожалуйста.

    В AsyncTask во время работы парсера в ArrayList заношу ссылки на картинки:
    titleUrl.add("\"" + titles.absUrl(absUrl) + "\"")

    Потом заношу все ссылки в массив:
    IMAGES = titleUrl.toArray(new String[titleUrl.size()])

    Через Intent передаю массив в другую Activity и там же его принимаю. При запуске приложения видно, что данные из массива считываются...создаётся нужное количество ImageView и TextView, но вместо загруженного изображения отображается изображение, которое должно отображаться при ошибке загрузки. Покапался в логах и увидел, что при загрузке каждого изображения выдаётся сообщение: UIL doesn't support scheme(protocol) by default [ссылка на изображение]. You should implement this support yourself (BaseImageDownloader.getStreamFromOtherSource(...))

    Всего пару дней занимаюсь разработкой приложений, но психов уже накопилось немеренно...удивляюсь, как ноутбук всё еще цел :) Буду очень благодарен, если поможете!

    ReplyDelete
    Replies
    1. Судя по ошибке у вас неправильные УРЛы. Похоже они начинаются на "protocol://" или что-то типа того. Проверьте в дебаге.

      Delete
    2. В том-то и дело, что перед этой ошибкой выдаются следующие сообщения:
      Start display image task ["http://4put.ru/pictures/max/843/2590221.jpg",_144x144]
      Load image from network ["http://4put.ru/pictures/max/843/2590221.jpg",_144x144]
      Cache image on disc ["http://4put.ru/pictures/max/843/2590221.jpg",_144x144]

      Судя по этим сообщениям, УРЛы у меня правильные, да и сам проверял массив выводом в TextView, всё заполняется правильно, точно так же, как и стандартный, уже заполненный массив...единственное отличие между ними - это ссылки. Поэтому то я и завис, потому что по логике всё правильно, но на практике не работает.

      Delete
    3. Похоже у вас в УРЛы кавычки содержат, это неправильно.

      Delete
    4. Вот если честно, много раз пробовал и с кавычками, и без кавычек, и так, и сяк...но сейчас оставил только titleUrl.add(titles.absUrl(absUrl)) и чудо, всё заработало,ура,наконец-то!) Я добавлял УРЛы с кавычками,т.к. видел, что в массиве они хранятся именно в таком виде и думал,что так правильно. Спасибо большое за помощь, премного благодарен!

      Delete
    5. Единственный косяк, это изображения почему-то снизу размытые и растянутые получаются...т.е. верхняя часть изображения нормальная, а нижняя с дефектами.

      Delete
  50. Anonymous6/2/14 16:36

    День добрый, подскажите пожалуйста.
    Использую Ваш universal image loader, добавляю картинки после парсинга в listview. все работает чудесно и все отображается, но проблем в том, что при скроллинге (я так понимаю, при потери фокуса на list элементе) картинка сбрасывается и если быстро заскролить несколько элементов, но нужно ждать пока картинки снова появяться в imageview. Для примера, в приложении для Вконтакта, все картинки в ленте новостей кэшируется на своих местах и не переотображаются. Где можно поискать решение данного вопроса. В ваше альгоритме или вне его?

    ReplyDelete
    Replies
    1. Добрый день. Вы включили кэширование?

      Delete
  51. Anonymous11/2/14 00:34

    День добрый, подскажите пожалуйста.
    Использую Ваш universal image loader, все работает чудесно и все отображается, но только в AVD, на телефоне или планшете вылетает с ошибкой. Куда посмотреть?

    ReplyDelete
    Replies
    1. Anonymous11/2/14 12:03

      дикие извинения, это я накосячил =)

      Delete
  52. Anonymous23/2/14 14:13

    Здравствуйте Сергей ,спасибо за библиотеку она очень хороша..

    у меня ошибка вот лог


    02-23 15:02:05.499: E/ImageLoader(31372): null
    02-23 15:02:05.499: E/ImageLoader(31372): java.lang.OutOfMemoryError
    02-23 15:02:05.499: E/ImageLoader(31372): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
    02-23 15:02:05.499: E/ImageLoader(31372): at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:613)
    02-23 15:02:05.499: E/ImageLoader(31372): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:589)
    02-23 15:02:05.499: E/ImageLoader(31372): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decodeStream(BaseImageDecoder.java:158)
    02-23 15:02:05.499: E/ImageLoader(31372): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:74)
    02-23 15:02:05.499: E/ImageLoader(31372): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:290)
    02-23 15:02:05.499: E/ImageLoader(31372): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:244)
    02-23 15:02:05.499: E/ImageLoader(31372): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:131)
    02-23 15:02:05.499: E/ImageLoader(31372): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    02-23 15:02:05.499: E/ImageLoader(31372): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    02-23 15:02:05.499: E/ImageLoader(31372): at java.lang.Thread.run(Thread.java:841)

    Спасибо,

    ReplyDelete
    Replies
    1. Anonymous23/2/14 15:55

      Если даю картины с маленькими размерами то нормально но когда больши(hd) то это проблема..

      Delete
    2. Anonymous23/2/14 21:34

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

      Delete
    3. Присоединяюсь, такая же проблема.

      Delete
  53. Размер можно поменять в конфигурации. .memoryCacheSize()

    ReplyDelete
    Replies
    1. Anonymous23/2/14 22:39

      Ну а в чем причина java.lang.OutOfMemoryError ? я понимаю что заполняется кэш , но где увеличить его размер ?

      Delete
    2. Если OutOfMemoryError, то размер кэша наоборот стоит уменьшать. Или вообще отказаться от кэширования в памяти. Если даже это не поможет, то значит у вас где-то утечка памяти.

      Delete
  54. Anonymous26/2/14 21:31

    Здравствуйте Сергей ,как можно реализовать ImageLoader в AsyncTask , я имею ввиду как читать с кэша в AsyncTask

    ReplyDelete
    Replies
    1. Здравствуйте, не понимаю что вы хотите.

      Delete
  55. Anonymous27/2/14 12:32

    Здравствуйте Сергей , заполняется оперативная память (240 mb на galaxy s3 ) в чем может быт проблема ?

    Спасибо

    ReplyDelete
    Replies
    1. Здравствуйте. Не знаю.

      Delete
  56. Anonymous4/3/14 01:12

    Здраствуйте Сергей! Как сделать что бы в ImageListActivity маленькие картинки загружались с отдельных ссылок, а в ImagePageActivity загружались другие ссылки (картинки)????

    ReplyDelete
    Replies
    1. Здавствуйте, понятия не имею, о чем вы.

      Delete
    2. Anonymous6/3/14 06:30

      я хочу что бы вы помогли сделать разные потоки загрузки! в ImageListActivity загружаются картинки одни, а в ImageGridActivity другие, и в ImageGalleryActivity другие!

      Delete
  57. Anonymous4/3/14 23:04

    Здраствуйте Сергей! Как сделать что бы ImageListActivity загружались одни картинки, а в другой ImageGridActivity другие?

    ReplyDelete
  58. Anonymous5/3/14 23:09

    English Version is a 404 :(

    ReplyDelete
  59. Добрый день!
    При использовании опции .displayer(new RoundedBitmapDisplayer(100)), информация о масштабировании игнорируется и отображается верхний левый угол картинки, тогда как у ImageView стоит android:scaleType="centerCrop".
    Подскажите, как можно отобразить центр картинки, и при этом закруглить углы?

    ReplyDelete
    Replies
    1. Добрый. RoundedBitmapDisplayer не покрывает некоторые случаи, думаю, вам стоит использовать более продвинутую вариацию для скругления - читайте в доках к RoundedBitmapDisplayer.

      Delete
    2. Большое спасибо за ответ и за такую обширную документацию :)
      Подключил https://github.com/vinc3m1/RoundedImageView , всё заработало.

      Delete
  60. Здравствуйте. Есть такая проблема: фотка по одному и тому же урлу может менятся. Кеш отключать не вариант. Есть ли возможность настроить UIL для этого случая? Или что переписать для этого(например проверять хедер lastModified)?

    ReplyDelete
    Replies
    1. Можете унаследовать BaseImageDownloader и там добавить проверку lastModified и если надо, то удаляйте картинку из кэшей (MemoryCacheUtil и DiscCacheUtil для этого).
      Или можете использовать кэши LimitedAge***Cache, которые удаляют закэшированные картинки периодически.

      Delete
  61. Здравствуйте, столкнулся с небольшой проблемой. Подскажите пожалуйста что можно сделать. Вот лог ошибки:

    java.io.FileNotFoundException: http://is431.tfs.intravision.ru/api/taskfile/3769
    at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
    at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStreamFromNetwork(BaseImageDownloader.java:120)
    at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStream(BaseImageDownloader.java:84)
    at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.getImageStream(BaseImageDecoder.java:94)
    at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:74)
    at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:264)
    at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:237)
    at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:135)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:841)

    Я так понимаю не может найти файл. К сожалению невозможно указать путь к фаилу (API серверной части не позволяет), по запросу сервер возвращает изображение побитово. Что нужно сделать? Заранее благодарен за ответ.

    ReplyDelete
    Replies
    1. Тогда вам надо перегрузить BaseImageDownloader.getStreamFromNetwork() и реализовать там побитовую загрузку изображения.Можете загрузить все в массив байт а потом вернуть new ByteArrayInputStream(bytes).

      Delete
  62. Anonymous2/7/14 03:38

    Здравствуйте. У меня такой вопрос : Как можно захэшировать картинку в DiskHash без моментальной погрузки в ImageView ?

    ReplyDelete
    Replies
    1. Здравствуйте. Можно воспользоваться методом loadImage(...).

      Delete
  63. Anonymous6/11/14 12:59

    Здравствуйте, у меня такой вопрос, можно ли вернуть картинку не ImageView, а в Bitmap ?

    ReplyDelete
    Replies
    1. Используйте loadImage(...) с колбэком onLoadingComplete().

      Delete
  64. Добрый день, искал и наконец-то нашел, суперская библиотека, спасибо разработчикам.
    У меня назрел такой вопрос с помощью showImageOnLoading(..) можно определить временную картинку, до загрузки основной, но она статична, а можно ли залепить туда анимацию какую нить,или передать список картинок для анимации, или может есть дефолтные какие методы?

    ReplyDelete
    Replies
    1. Добрый. Опишите анимацию в drawable и передавайте в showImageOnLoading(...).

      Delete
  65. Здравствуйте Сергей! Спасибо за UIL! При использовании RecyclerView, адаптер в незагруженых айтемах показывет картинки из других айтемов где картинка уже подгрузилась, пробовал бороться, но все никак( прошу помощи в реализации подобного адаптера.

    ReplyDelete
    Replies
    1. Здравствуйте. Покажите свои DisplayImageOptions.

      Delete
    2. public static void initImageLoader(Context context)
      {

      DisplayImageOptions options = new DisplayImageOptions.Builder()
      .cacheInMemory(true)
      .cacheOnDisk(true)
      .considerExifParams(true)
      .bitmapConfig(Bitmap.Config.RGB_565)
      .build();
      ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
      .threadPriority(Thread.NORM_PRIORITY - 2)
      .denyCacheImageMultipleSizesInMemory()
      .diskCacheFileNameGenerator(new Md5FileNameGenerator())
      .diskCacheSize(50 * 1024 * 1024) // 50 Mb
      .tasksProcessingOrder(QueueProcessingType.LIFO)
      .defaultDisplayImageOptions(options)
      .build();

      ImageLoader.getInstance().init(config);
      }
      Инициализация в App.

      Delete
    3. Добавьте опцию resetViewBeforeLoading() в DisplayImageOptions.

      Delete
    4. Спасибо! Помогло.

      Delete
  66. This comment has been removed by the author.

    ReplyDelete
  67. Сергей,привет!
    Не подскажешь,можно ли как то вытянуть "правильные" EXIF значения с изображения,посредством UIL? Спасибо!

    ReplyDelete
  68. Anonymous21/1/16 14:49

    Здравствуйте, Сергей! Спасибо Вам огромное за библиотеку. Подскажите, пожалуйста, дизайнеры попросили реализовать следующий функционал: на месте изображения, пока оно загружается, должны отображаться 5 картинок по очереди. Подобный функционал для отображения картинок при ошибке при загрузке сделал, а тут не могу понять как. Думал, что просто в onLoadingStarted реализую, но не выходит. Заранее прошу прощения, если криво описал.

    ReplyDelete
  69. Здравствуйте, может кто подскажет как получить исходную ссылку изображения по выбранному пользователем view (из галереи всех подгруженных изображений)? Хочу реализовать функцию удаления выбранного изображения. Спасибо.

    ReplyDelete
  70. Anonymous25/3/16 00:05

    По какой директории и с каким именем сохраняется файл при использовании метода loadImage, если используется стандартная конфигурация? Как обращаться потом к нему, чтобы этот файл достать из диска?

    ReplyDelete
  71. Спасибо за ваш великий пост.

    Я хотел бы предложить всем, чтобы проверить http://quizbucket.org/quiz/android для андроид викторины и вопросы интервью, это может быть полезно для тех, кто готовится к собеседованию

    ReplyDelete