2012-01-26 2 views
1

Я работаю над приложением, которое использует динамически заполненный список, в котором каждый элемент содержит изображение, которое необходимо загрузить. Кроме того, при нажатии на любой элемент в списке открывается подробная страница, которая еще раз показывает одно и то же изображение в дополнение к нескольким другим.Использование ImageDownloader с кэшированием не кэширования

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

После того, как вы искали немного, я использовал код примера Google, расположенный по адресу http://developer.android.com/resources/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.html, который утверждает, что является как методом асинхронного, так и кэширования для загрузки изображений.

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

Часть кода в моем пользовательском классе (который строит вид списка), где я называю загрузку изображения заключается в следующем:

ImageDownloader getimage = new ImageDownloader(); 
getimage.download(logoURL, ivLogo); 

С ImageDownloader является класс упомянутых выше.

Загрузка изображений, но очевидно, что они загружаются из Интернета каждый раз. Я добавил некоторые записи в ImageDownloader.class, чтобы отслеживать, что происходит, когда. Я обнаружил, что при первом обращении к изображению он не выполняет первый вызов для получения из кеша (как и ожидалось), getBitmapFromCache возвращает значение null и вызывается принудительная загрузка.

public void download(String url, ImageView imageView, String cookie) { 
    resetPurgeTimer(); 
    Bitmap bitmap = getBitmapFromCache(url); 
    Log.i(LOG_TAG, "Bitmap is: " + bitmap); 

    if (bitmap == null) { 
     Log.i(LOG_TAG, "Forcing Download"); 
     forceDownload(url, imageView, cookie); 
    } else { 
     cancelPotentialDownload(url, imageView); 
     imageView.setImageBitmap(bitmap); 
    } 
} 

Как исполнение прогрессирует вниз класса до точки, где она добавляет изображение/URL в кэше

private void addBitmapToCache(String url, Bitmap bitmap) { 
    Log.i(LOG_TAG, "Incoming Add Cache Info: URL: " + url + " Bitmap: " + bitmap); 
    if (bitmap != null) { 
     Log.i(LOG_TAG, "Entering the add image to cache section"); 
     synchronized (sHardBitmapCache) { 
      sHardBitmapCache.put(url, bitmap); 
      Bitmap returnedbitmap = getBitmapFromCache(url); 
      Log.i(LOG_TAG, "Returned bitmap immediately after adding: " + bitmap); 
     } 
    } 
} 

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

Incoming request to get Image, URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Trying Hard Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Hard Bitmap is: null 

Trying Soft Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Return from initial entry call: null 

Entering forced Download 

Incoming Add Cache Info: URL:http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.pngBitmap: [email protected] 

Entering the add image to cache section 

Trying Hard Cache withURL: http://www.yourlogoresources.com/wpcontent/uploads/2011/11/Wendys-logo.png 

Hard Bitmap is: [email protected] 

Returned bitmap immediately after adding:[email protected] 

Так появляется кэш заселяется должным образом, однако, в следующий раз, когда запрашивается, что изображение (т.е. при прокрутке ListView), кэшированные изображения снова не найдено с getBitmapFromCache (URL) возвращением нуля из точка входа скачать.

Incoming request to get Image, URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Trying Hard Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Hard Bitmap is: null 

Trying Soft Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Return from initial entry call: null 

Entering forced Download 

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

EDIT

Я закончил с использованием статической ссылки на ImageDownloader от моей основной деятельности следующим образом:

public class myActivity extends Activity implements OnClickListener { 
    public final static ImageDownloader GetImage = new ImageDownloader(); 

Тогда называется, что как эти, где мне нужен ImageDownload:

myActivity.GetImage.download(logoURL, ivLogo); 

Спасибо за помощь всем.

ответ

1

Просмотрите код ImageDownloader.

Он использует первичный кэш private final HashMap<String, Bitmap> sHardBitmapCache

и вторичного кэш статического private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache

Запись выгнала из первичного кэша помещается в кэш вторичного.

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

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

+0

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

+0

И, чтобы уточнить, у меня есть класс Activity, который делает начальный вызов классу CustomAdapter (с массивом как вход), который, в свою очередь, вызывает класс ImageDownloader для каждой записи в массиве. Будучи действительно новым для Java, я просто не уверен, как я собираюсь создать экземпляр только одного экземпляра ImageDownloader, но иметь доступ к нему из нескольких других классов. Любые указатели будут оценены. – brad

+0

Вы можете открыть экземпляр ImageDownloader через объект Application. Вот пример: http://stackoverflow.com/questions/708012/android-how-to-declare-global-variables. Или вы могли бы просто сделать его статическим объектом. –

Смежные вопросы