Я работаю над приложением, которое использует динамически заполненное представление списка, в котором каждый элемент содержит изображение, которое необходимо загрузить. Кроме того, при нажатии на любой элемент в списке открывается подробная страница, которая еще раз показывает одно и то же изображение в дополнение к нескольким другим.
Как известно, лучше всего использовать задачу 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);
Спасибо за помощь всем.
Посмотрите на код ImageDownloader
.
Он использует основной private final HashMap<String, Bitmap> sHardBitmapCache
кеш- private final HashMap<String, Bitmap> sHardBitmapCache
и вторичный статический кеш private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache
Записи, выбитые из основного кеша, помещаются во вторичный кеш.
Теперь, когда вы хотите загрузить изображение, если вы создаете новый экземпляр ImageDownloader
, вы фактически не используете механизм кэширования, потому что каждый экземпляр ImageDownloader
будет иметь только одно изображение, загруженное с помощью этого экземпляра.
PS: Ваш код в вопросе выглядел так, будто вы используете экземпляр для загрузки.