Chapter 26 Loopers, Handlers, and HandlerThread
In ThumbnailDownloader.handleRequest(), add the following code.
Listing 26.12 Downloading and displaying images
(ThumbnailDownloader.java)
public class ThumbnailDownloader
...
private Handler mResponseHandler;
private ThumbnailDownloadListener
...
private void handleRequest(final T target) {
try {
final String url = mRequestMap.get(target);
if (url == null) {
return;
}
byte[] bitmapBytes = new FlickrFetchr().getUrlBytes(url);
final Bitmap bitmap = BitmapFactory
.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);
Log.i(TAG, "Bitmap created");
mResponseHandler.post(new Runnable() {
public void run() {
if (mRequestMap.get(target) != url ||
mHasQuit) {
return;
}
mRequestMap.remove(target);
mThumbnailDownloadListener.onThumbnailDownloaded(target, bitmap);
}
});
} catch (IOException ioe) {
Log.e(TAG, "Error downloading image", ioe);
}
}
}
Because mResponseHandler is associated with the main thread’s Looper, all of the code inside of
run() will be executed on the main thread.
So what does this code do? First, you double-check the requestMap. This is necessary because the
RecyclerView recycles its views. By the time ThumbnailDownloader finishes downloading the Bitmap,
RecyclerView may have recycled the PhotoHolder and requested a different URL for it. This check
ensures that each PhotoHolder gets the correct image, even if another request has been made in the
meantime.
Next, you check mHasQuit. If ThumbnailDownloader has already quit, it may be unsafe to run any
callbacks.
Finally, you remove the PhotoHolder-URL mapping from the requestMap and set the bitmap on the
target PhotoHolder.