To get a better idea what is going on with thread in in this chapter I instrumented my code with log statements that included the thread id:
It was quite informative. It appears that although queueThumbnail is a method of the ThumbDownloaderHandler (TD), it executes in the context of the main thread that runs the UI for the fragment/activity. When queueThumbnail issues the obtainMessage and sendToTarget, it is doing so on the mHandler of the TD - this is because mHandler was instantiated in method onLoopPrepared of the TD thread, which implicitly associates the handler mHandler with the TD thread. Thus issuing mHandler.sendToTarget actually enqueues the message on the message queue of the TD thread FROM the main UI thread context.
This was not obvious to me although I guess the chapter described the capability but not in the clearest of terms from a tasking context perspective (I’m an old OS systems programmer trying to live in app-land so cut me a break!)
Additionally when the TD thread handles a message, it directly invokes the getUrlBytes method in the FlickrFetchr class which waits for the HTTP request to Flickr for the thumbnail to complete, then its last duty (before returning to looper) is to inform the main thread the Thumbnail download requested is completed by using the mResponseHandler. The handleRequest method is running in the context of the TD thread and its last act is to invoke the post() method of the mResponseHandler, which causes the runnable passed in as a parameter to post() to be scheduled for execution on the main thread. The next time the main thread runs it executes the runnable on the main thread and it invokes the previously setup Listener back in the fragment which shoves the bitmap to the view. This is all enabled by having the main thread pass in its handler on creation of the TD thread, to use as a hook for driving code to run in the Main thread to process the result (mResultHandler).
Looking at the threadids really helped understand the tasking aspects and the IPC! Great chapter!