Android Coder: Using a Dedicated Background Thread for NixMashupLink Images

We talked about using a background thread to retrieve the NixMashup Links XML data from the API server.  We're going to take that one step further and describe how we'll use a dedicated background thread, along with Android's Looping and Messaging architecture to retrieve NixMashupLink Thumbnail images on an as-needed basis.

There are two problems in downloading the thumbnails as part of the LinkFetchr background task we used to retrieve the XML data. The first is that it could take a while, and two, the UI would not be updated until the downloading all of the images was complete.

In addition we need to think of storing all of the NixMashup Link thumbnails once they are downloaded, as there are currently near 1000 links and I have no intention of stop publishing new NixMashup Links any time soon.

Given these problems, we're going to create a dedicated background thread and download image bitmaps only when they need to be displayed on screen.

The XML Image Data

Let's review the image data before looking at how we'll download the bitmap image content in our background thread. We're starting with String data consisting of the base filename of the image, which in various sizes is used throughout the app. (More about the images used in NixMashupLinks is found in my Seasonal Photos blog posts.)

Here's the XML data downloaded by the LinkFetchr background task.

We're going to pass the NixMashupLink data object parsed from the XML file shown above, or “IMG1229002.” Our dedicated background thread will return the data object along with a bitmap of the thumbnail image we'll use to populate the ImageView.

LinkDownloader Background Thread and HandlerThread

Android threads use message queues and a Looper object that manages the queue. Everything the main thread does is performed by its looper, which grabs messages off of its message queue and performs the task it specifies. The background thread we create is also a message loop, and a class called HandlerThread will prepare the Looper for us.

Here's the LinkDownloader background thread class in its entirety so you have an idea of its moving parts.

Our LinkDownloader extends HandlerThread. The thread will need to use some object to identify each download, so we give it a generic argument called Token and will pass our View as the token from LinkListFragment.

In LinkListFragment onCreate() we create a new instance of the LinkDownloader<Token> class (passing our View as the token) and set a listener to the onLinkDownloaded() Interface method in LinkDownloader<Token>. onLinkDownloaded() will be executed in the background thread with three parameters, the view to be populated, the NixMashupLink data object containing the link title, description and so forth, and third, the bitmap image of the thumbnail image. mLinkDownloadThread.start() and .getLooper() ensure that the background thread is ready before proceeding.

Queue the Link!

We talked about processing only the links we require at the time of display, not all of the links available. To do that we process each link in LinkAdapter(), adding the link to the background thread message queue with queueLink(convertView, link).

Our LinkDownloader Thread takes the NixMashupLink data object (which also contains the url to our image thumbnail), and places it in a synchronized Collections HashMap object we defined at the top of the class with Map<Token, NixMashupLink> requestMap. The thread then sends the object to the handler's target which we defined in the LinkDownloader onLooperPrepared() method,  handleRequest(final Token token) {…}.

Handling the Task and Populating the View

LinkDownloader handleRequest() completes the task of creating the thumbnail bitmap and sending it back to the main thread in LinkListFragment, along with the view token and NixMashupLink data object through the Interface onLinkDownloaded() Listener method.

Back in LinkListFragment

Link by link, thumbnail by thumbnail, we process the view contents as we need them to appear on the screen when onLinkDownloaded() is triggered. As you can see, in onLinkDownloaded() we are populating the view contents like in any typical onCreateView() method.

It's a Wrap

We touched on a lot in creating a dedicated background thread. There are other aspects of housekeeping and so forth which we didn't cover, but the complete source is in the NixMashupLinks GitHub repository if you want to walk through the process.

Android Coder Notes for this Post

Using a dedicated background thread was implemented in NixMashupLinks from the initial Version 1.0.1 Branch in the repository.

Posted December 14, 2014 05:22 PM EST

More Like This Post