Android-Universal-Image-Loader
Android-Universal-Image-Loader copied to clipboard
Problem with loadImage() when loading same image url
There is an article detail activity with a comment list in my app. Every list item has a custom avatar view, so I use method loadImage
instead of displayImage
to load image from network or cache. When the comment avatar views load the image with the same url (the same user posts many comments), only part of views can display the image.
I found the reason in class DisplayBitmapTask
@Override
public void run() {
if (imageAware.isCollected()) {
L.d(LOG_TASK_CANCELLED_IMAGEAWARE_COLLECTED, memoryCacheKey);
listener.onLoadingCancelled(imageUri, imageAware.getWrappedView());
} else if (isViewWasReused()) {
L.d(LOG_TASK_CANCELLED_IMAGEAWARE_REUSED, memoryCacheKey);
listener.onLoadingCancelled(imageUri, imageAware.getWrappedView());
} else {
L.d(LOG_DISPLAY_IMAGE_IN_IMAGEAWARE, loadedFrom, memoryCacheKey);
displayer.display(bitmap, imageAware, loadedFrom);
engine.cancelDisplayTaskFor(imageAware);
listener.onLoadingComplete(imageUri, imageAware.getWrappedView(), bitmap);
}
}
when the first thread finished the load task, it will call engine.cancelDisplayTaskFor(imageAware)
void cancelDisplayTaskFor(ImageAware imageAware) {
cacheKeysForImageAwares.remove(imageAware.getId());
}
So when the other thread loaded the image from cache or network and go to the DisplayBitmapTask
, the condition isViewWasReused()
method return false
because the record in map cacheKeysForImageAwares
has been removed by the first thread with the same ImageAware
id.
/** Checks whether memory cache key (image URI) for current ImageAware is actual */
private boolean isViewWasReused() {
String currentCacheKey = engine.getLoadingUriForView(imageAware);
return !memoryCacheKey.equals(currentCacheKey);
}
loadImage
method use NonViewAware
to reuse the logic of displayImage
. But the getId()
return the hashcode of the image url instead of its hashcode.
@Override
public int getId() {
return TextUtils.isEmpty(imageUri) ? super.hashCode() : imageUri.hashCode();
}
It's the reason causing the bug. I don't know the benifit using imageUri.hashCode();
. But following code is fine
@Override
public int getId() {
return super.hashCode();
}
this bug still alive!