Combining Handler and AsyncTask in Android - Obvious Flaws?
<p>I have a simple Android app which uses AsyncTasks for I/O. A frequent pattern:</p>

<ul>
<li>User clicks a button</li>
<li>In response, an onClick handler instantiates and .execute()s an AsyncTask</li>
<li>Once the AsyncTask completes, the UI should be updated in some way</li>
</ul>

<p>According to the documentation for AsyncTask, the correct way to accomplish the UI updates is to override onPostExecute in the AsyncTask class - this will be invoked back on the UI thread after execution and thus can touch the widgets, etc. </p>

<p>However, it seems wrong to me that onPostExecute should have any sort of hard reference to a UI element. I would prefer to keep my I/O tasks and UI code separate. Instead, this seems the obvious situation where I should pass an opaque callback to the AsyncTask - the callback retains a reference to the UI elements and thus we maintain isolation and reusability in the code. A classic delegate pattern (or perhaps listener, event, etc, many options here).</p>

<p>As an example, the code below seems wrong to me:</p>

<pre><code>    class QueryJobsDBTask extends AsyncTask&lt;Void, Void, ArrayList&lt;ContentValues&gt;&gt; {

    @Override
    protected void onPostExecute(ArrayList&lt;ContentValues&gt; freshJobsData) {
        someList.clear();
        someList.addAll(freshJobsData);

        // BUG why does my DB query class hold UI references?
        someAdapter.notifyDataSetChanged();
    }
</code></pre>

<p>After some research, it looks like the Handler class is the most straightforward and lightweight way to accomplish a delegate pattern here. I can write reusable AsyncTasks for I/O and specify contextual UI update callbacks on a per-instance basis via Handler instances. So I have implemented this new Handler-enabled base class</p>

<pre><code>   public abstract class HandlerAsyncTask&lt;Params, Progress, Result&gt; extends AsyncTask&lt;Params, Progress, Result&gt; {
    private Handler preExecuteHandler, postExecuteHandler;

    public void setPreExecuteHandler(Handler preExecuteHandler) {
        this.preExecuteHandler = preExecuteHandler;
    }

    public void setPostExecuteHandler(Handler postExecuteHandler) {
        this.postExecuteHandler = postExecuteHandler;
    }

    @Override
    protected void onPreExecute() {
        if (preExecuteHandler != null) {
            preExecuteHandler.sendMessage(Message.obtain());
        }
    }

    @Override
    protected void onPostExecute(Result result) {
        if (postExecuteHandler != null) {
            Message msg = Message.obtain();
            msg.obj = result;
            postExecuteHandler.sendMessage(msg);
        }
    }
}
</code></pre>

<p>And voila, all of my I/O tasks are now properly partitioned from the UI - and I can still specify simple UI update callbacks when needed via Handler instances. This seems straightforward, flexible, and superior to me ... so of course I wonder what I'm missing.</p>

<p><strong>How is the current framework solution superior?</strong> Is there some major pitfall to this approach? To my knowledge the topology of code execution and threads is the exact same at runtime, just code coupling is looser (and a few extra frames on the stack). </p>
