Lisa Anne
Lisa Anne

Reputation: 4595

Getting results from several AsyncTasks

Hi and thanks for your help.

I have a method that calls an AsyncTask to retrieve some data from the net.

The method is called several times in sequence and therefore launches several AsyncTasks.

From each launch of the method I need to get back the correct result from the relative AsyncTask (and not from some other AsyncTask which was called before or after).

Any help very much appreciated.


EDIT EDIT EDIT EDIT Added rest of code.

Please Note: the whole process runs inside a Service.

public static class UpdateService extends Service {
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        int[] appWidgetIds = intent.getIntArrayExtra("widgetsids");
        final int N = appWidgetIds.length;
        AppWidgetManager manager = AppWidgetManager.getInstance(this);
        for (int i = 0; i < N; i++) {
            int appWidgetId = appWidgetIds[i];
            Log.e("","i="+Integer.toString(i)+ " di "+Integer.toString(N));
            RemoteViews view = buildUpdate(getApplicationContext(),
                    appWidgetIds);
            manager.updateAppWidget(appWidgetId, view);
        }
        return (START_NOT_STICKY);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

private static  RemoteViews buildUpdate(Context ctxt, int[] appWidgetIds) {
    RemoteViews updateViews = new RemoteViews(ctxt.getPackageName(),
            R.layout.widget);
        updateViews.setTextViewText(R.id.price1, getPrice(list.get(0)
            .getSymbol()));

 }        
    //THIS METHOD IS CALLED SEVERAL TIMES IN SEQUENCE    <----
    private static String getPrice(String symbol) {
    String result="";
    UpdateTaskPrice up = new UpdateTaskPrice();
    up.execute(symbol, null, null);
    //HERE I WANT THE RESULT FROM onPostExecute()    <----
    return result;
}

//THIS IS THE ASYNCTASK WHICH IS LAUNCHED SEVERAL TIMES
public class UpdateTaskPrice extends AsyncTask<String, Void, String> {

    @Override
    protected void onProgressUpdate(Void... progress) {
    }

    @Override
    protected void onPostExecute(String result) {
    //HERE I RECEIVE THE RESULT FROM doInBackground    <----
    //I NEED TO PASS IT BACK TO getPrice()    <----
    }

    @Override
    protected String doInBackground(String... symbol) {
        String result = "";
        DefaultHttpClient client = new DefaultHttpClient();
        String srt = "";

        String url = context.getString(R.string.urlaternativo).concat(
                symbol[0]);

        HttpGet getMethod = new HttpGet(url);
        try {
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            srt = client.execute(getMethod, responseHandler);
            int inizio = srt.indexOf("<last data=\"");
            int fine = srt.indexOf("\"/>", inizio + 12);
            result = srt.substring(inizio + 12, fine);

        } catch (Throwable t) {
            // Log.e("ERROR", "ERROR", t);
        }
        //HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute()    <----
        return result;
    }
}

Upvotes: 7

Views: 1477

Answers (3)

jaibatrik
jaibatrik

Reputation: 7533

Well, I think you can pass the unique request id in the constructor of the AsyncTask. Then in the postExecute() method, update the UI with the result and the unique request id -

public class UpdateTaskPrice extends AsyncTask<String, Void, String> {

    private int mIdentifier;
    private Service mService;

    public UpdateTaskPrice(Service service, int identifier) {
        this.mIdentifier = identifier;
    }

    @Override
    protected void onProgressUpdate(Void... progress) {
    }

    @Override
    protected void onPostExecute(String result) {
        ((UpdateService) mService).informPrice(mIdentifier, result);
    }

    @Override
    protected String doInBackground(String... symbol) {
        String result = "";
        DefaultHttpClient client = new DefaultHttpClient();
        String srt = "";

        String url = context.getString(R.string.urlaternativo).concat(
                symbol[0]);

        HttpGet getMethod = new HttpGet(url);
        try {
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            srt = client.execute(getMethod, responseHandler);
            int inizio = srt.indexOf("<last data=\"");
            int fine = srt.indexOf("\"/>", inizio + 12);
            result = srt.substring(inizio + 12, fine);

        } catch (Throwable t) {
            // Log.e("ERROR", "ERROR", t);
        }
        //HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute()    <----
        return result;
    }
}

Upvotes: 0

Nixit Patel
Nixit Patel

Reputation: 4445

You can get the data from multiple asynctask, but the place you want the result is not possible with the asyctask, you need to use more encapsulation to structure this problem.

the problem with your structure is...

 private static String getPrice(String symbol) {
    String result="";
    UpdateTaskPrice up = new UpdateTaskPrice();
    up.execute(symbol, null, null);
    //HERE I WANT THE RESULT FROM onPostExecute()    <----
    return result;
}

when you are starting the new thread it will first execute the statement which is return after task.execute(symbol); in your case it is return statement and then it will exucute pre.. doin.. and post...

Hear is the pattern which you can use to retrieve the data from multiple AsycTask

//Calling to the method callAsyncTask;
callAsyncTask(new AsyncResultCallback(){
    public void onResult(String result, String symbol){
        //TODO dosomthing with the result
    }
});


public void callAsyncTask(AsyncResultCallback callback){
    new UpdateTaskPrice(callback).execurte(symbol);
}

public interface AsyncResultCallback{
    public void onResult(String result, String symbol);
}

public class UpdateTaskPrice extends AsyncTask<String, Void, String> {

    AsyncResultCallback callback;
    String symbol;

    UpdateTaskPrice(AsyncResultCallback callback){
        this.callback = callback;
    }

    @Override
    protected void onProgressUpdate(Void... progress) {
    }

    @Override
    protected void onPostExecute(String result) {
        callback.onResult(result, symbol);
    }

    @Override
    protected String doInBackground(String... symbol) {
        this.symbol = symbol;
        String result = "";
        DefaultHttpClient client = new DefaultHttpClient();
        String srt = "";

        String url = context.getString(R.string.urlaternativo).concat(symbol[0]);

        HttpGet getMethod = new HttpGet(url);
        try {
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            srt = client.execute(getMethod, responseHandler);
            int inizio = srt.indexOf("<last data=\"");
            int fine = srt.indexOf("\"/>", inizio + 12);
            result = srt.substring(inizio + 12, fine);

        } catch (Throwable t) {
            // Log.e("ERROR", "ERROR", t);
        }
            //HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute()    <----
        return result;
    }
}

hope that help.

Upvotes: 0

Amit
Amit

Reputation: 1385

AsyncTask is asynchronous and run in a separate thread. So it is not possible to get the result of AsyncTask in very next statement after you execute it.

To get the relative results from AsyncTask, add a member variable "mRequestId" in your UpdateTaskPrice class and before calling UpdateTaskPrice.execute, set unique request ID.

in "onPostExecute" method of your UpdateTaskPrice class, you can return and process result using this Request Id.

public class UpdateTaskPrice extends AsyncTask<String, Void, String> {

    protected int mRequestId;

    public void setRequestId (int requestId)
    {
        this.mRequestId = requestId;
    }

    @Override
    protected void onProgressUpdate(Void... progress) {
    }

    @Override
    protected void onPostExecute(String result) {
        // do whatever with result using mRequestId
    }

    @Override
    protected String doInBackground(String... symbol) {
        String result = "";
        DefaultHttpClient client = new DefaultHttpClient();
        String srt = "";

        String url = context.getString(R.string.urlaternativo).concat(
                symbol[0]);

        HttpGet getMethod = new HttpGet(url);
        try {
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            srt = client.execute(getMethod, responseHandler);
            int inizio = srt.indexOf("<last data=\"");
            int fine = srt.indexOf("\"/>", inizio + 12);
            result = srt.substring(inizio + 12, fine);

        } catch (Throwable t) {
            // Log.e("ERROR", "ERROR", t);
        }
        //HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute()    <----
        return result;
    }
}

Upvotes: 10

Related Questions