Использование ImageDownloader с кэшем, а не кэшированием

1

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

Как известно, лучше всего использовать задачу 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: android.graphics.Bitmap@40762f28

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: android.graphics.Bitmap@40762f28

Returned bitmap immediately after adding:android.graphics.Bitmap@40762f28

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

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

Поэтому я затрудняюсь объяснить, почему в нем отображается кеш, но когда он снова проверяется, возвращается только значение null.

РЕДАКТИРОВАТЬ

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

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

Затем я назвал это так, как мне нужно, чтобы ImageDownload:

    myActivity.GetImage.download(logoURL,  ivLogo);

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

Теги:

1 ответ

1
Лучший ответ

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

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

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

Записи, выбитые из основного кеша, помещаются во вторичный кеш.

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

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

  • 0
    Викрам, да, я верю, что вы правы, я выставляю новый экземпляр для каждого изображения. Я предполагаю, что должен найти способ поднять только один экземпляр ImageDownloader и просто использовать этот единственный экземпляр для каждой загрузки?
  • 0
    И чтобы уточнить, у меня есть класс Activity, который выполняет первоначальный вызов класса CustomAdapter (с массивом в качестве входных данных), который, в свою очередь, вызывает класс ImageDownloader для каждой записи в массиве. Будучи действительно новичком в Java, я просто не уверен, как бы мне создать экземпляр только одного экземпляра ImageDownloader, но получить доступ к нему из нескольких других классов. Любые указатели будут оценены.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню