3

I'm writting an app that uses WebServices to retrieve data. Initially I had a private AsyncTask class for each activity that needed data from the WebService. But I've decided to make the code simpler by creating AsyncTask as a public class. All works fine, but my problem is when I want to access the retrieved data from the AsyncTask.

For example this is my AsyncTask class.

public class RestServiceTask extends AsyncTask<RestRequest, Integer, Integer> {

    /** progress dialog to show user that the backup is processing. */
    private ProgressDialog dialog;
    private RestResponse response;
    private Context context;

    public RestServiceTask(Context context) {
        this.context = context;

        //...Show Dialog
    }

    protected Integer doInBackground(RestRequest... requests) {
        int status = RestServiceCaller.RET_SUCCESS;
        try {
            response = new RestServiceCaller().execute(requests[0]);
        } catch(Exception e) {
            //TODO comprobar tipo error
            status = RestServiceCaller.RET_ERR_WEBSERVICE;
            e.printStackTrace();
        }

        return status;
    }

    protected void onPreExecute() {
        response = null;
    }

    protected void onPostExecute(Integer result) {

        if (dialog.isShowing()) {
            dialog.dismiss();
        }

        switch (result) {
        case RestServiceCaller.RET_ERR_NETWORK:
            Toast.makeText(
                    context,
                    context.getResources().getString(
                            R.string.msg_error_network_unavailable),
                    Toast.LENGTH_LONG).show();
            break;
        case RestServiceCaller.RET_ERR_WEBSERVICE:
            Toast.makeText(
                    context,
                    context.getResources().getString(
                            R.string.msg_error_webservice), Toast.LENGTH_LONG)
                    .show();
            break;
        default:
            break;
        }
    }

    public RestResponse getResponse() throws InterruptedException {
        return response;
    }
}

RestServiceCaller, RestRequest and RestResponse are clasess that I've created. I'm using the task like this:

RestRequest request = new JSONRestRequest();
request.setMethod(RestRequest.GET_METHOD);
request.setURL(Global.WS_USER);
HashMap<String, Object> content = new HashMap<String, Object>() {
   {
      put(Global.KEY_USERNAME, username.getText().toString());
   }
};
request.setContent(content);
RestServiceTask task = new RestServiceTask(context);
task.execute(request);

This code works fine and is calling the web service correctly, my problem is when I want access to the response. In the AsyncTask I've created the method getResponse but when I use it, it returns a null object because the AsyncTask is still in progress, so this code doesn't work:

//....
task.execute(request);
RestResponse r = new RestResponse();
r = task.getResponse();

r will be a null pointer because AsyncTask is still downloading data.

I've try using this code in the getResponse function, but it doesn't work:

public RestResponse getResponse() throws InterruptedException {
        while (getStatus() != AsyncTask.Status.FINISHED);
        return response;
    }

I thought that with the while loop the thread will wait until the AsyncTask finishes, but what I achieved was an infinite loop.

So my question is, how could I wait until AsyncTask finishes so the getResponse method will return the correct result?

The best solution is use of the onPostExecute method, but because AsyncTask is used by many activities I have no clue what to do.

Alejandro Alcalde
  • 5,990
  • 6
  • 39
  • 79

1 Answers1

4

try creating a callback interface. The answer to this async task question Common class for AsyncTask in Android? gives a good explanation for it.

Community
  • 1
  • 1
Thomas
  • 2,751
  • 5
  • 31
  • 52