Bam
Bam

Reputation: 530

Return network SQL result into main UI thread in Android

I am looking for a way for the main (UI) thread in Android to get the results of an SQL query I run against a network SQL server.

I know your first answer might be to yell out "ASYNCTASK!!!", but bear with me and I'll explain why that is not what I'm looking for.

By using AsyncTask, I can already run the query and retrieve the result without any issues. What I am looking for is a way to be able to bundle all this together into one single call, that will return the result of the AsyncTask. See the pseudo code below:

public static Object returnQueryResults()
{
    // Perhaps show a "Loading" dialog

    // Start the AsyncTask that will query the SQL server

    // Here is the important part, somehow WAIT for the result 
    // to be returned or timed out or cancelled or whatever

    // return the result gotten by the AsyncTask
}

I know and fully understand that the WAIT portion of the function cannot be an actual wait() because that would block the UI thread and Android does not allow that, but what I am looking for is to be able to only have to call this single function to retrieve the result.

The issue, to me, seems to be how to pass the result from the postExecute of the AsyncTask to the main UI thread, while also having the UI thread wait for the result.

Any ideas would be appreciated as I have tried to solve this one on-and-off for a while now.

Upvotes: 1

Views: 163

Answers (2)

BladeCoder
BladeCoder

Reputation: 12929

AsyncTask runs onPostExecute() automatically on the UI thread so you don't have to do anything, you can populate your UI in that method. Just be careful and cancel your AsyncTask in onDestroy() for example to avoid delivering the result when the Activity is gone.

Upvotes: 0

Karakuri
Karakuri

Reputation: 38595

You can't do it in one method block. You need some kind of callback mechanism. AsyncTask by itself may not be the best framework for this, but assuming you stick with that, then it's as simple as defining an interface, implementing that interface in your Activity/Fragment/whatever, and passing the AsyncTask a reference to the implementor (e.g. in the constructor).

AsyncTask by itself may not be the best framework

public class MyAsyncTask extends AsyncTask<String, Void, MyQueryResult> {

    interface MyQueryResultCallback {
        void onQueryResult(MyQueryResult result);
    }

    // assuming you may implement the interface in an Activity/Fragment,
    // you probably shouldn't keep a strong reference to it because Android
    // can destroy and create new instances of those.
    private WeakReference<MyQueryResultCallback> callbackRef;

    public MyAsyncTask(MyQueryResultCallback callback) {
        callbackRef = new WeakReference<MyQueryResultCallback>(callback);
    }

    /* doInBackground omitted for brevity */

    @Override
    protected void onPostExecute(MyQueryResult result) {
        MyQueryResultCallback callback = callbackRef.get();
        if (callback != null) {
            callback.onQueryResult(result);
        }
    }
}

You would make one method to show the loading indicator and start the task, then your implementation of onQueryResult() would dismiss the loading indicator and update the UI.

Upvotes: 1

Related Questions