0

I'm trying to use AsyncTask to download a string and return the string. I want to use AsyncTask because it might take a while.

One problem is that nowhere on the internet can I find an example of an AsyncTask returning any kind of value. So I took the example in the Commonsware book and modified it to return a value and I get the value as follows:

String mystr = new AddStringTask().execute().get();

While this works, it seem that this line of code is waiting for the return value and therefore synchronous. There must be some way to have an event trigger with the results of the AddStringTask.

How is that done? Thanks, Gary

Dean Blakely
  • 3,535
  • 11
  • 51
  • 83
  • see this question: http://stackoverflow.com/questions/9447646/how-do-i-send-data-back-from-onpostexecute-in-an-asynctask/9447833#9447833 – Matt Wolfe Sep 17 '12 at 22:40

2 Answers2

2

An AsyncTask cannot return a value, because to get the returned value you would have to wait before the task is finished. That would make the AsyncTask meaningless.

Instead, you should move your code in onPostExecute() (which runs on the UI thread, if this is what you worry about). This is where you handle the value returned by doInBackground() and typically update the UI or show an error message.

Dalmas
  • 26,409
  • 9
  • 67
  • 80
  • Ok, I think I get it. onPostExecute is on the UI thread and it is analagous to the _completed event in the Microsoft WCF world. – Dean Blakely Sep 18 '12 at 23:18
  • One more way to get result from you AsyncTask in your activity. I just write on my blog and you can add it. you can refer below link http://smartphonebysachin.blogspot.in/2012/11/how-to-return-value-from-async-task-in.html – Sachin Shelke Nov 01 '12 at 08:07
0

Also if you wanted to implement a more general AsyncTask you could implement something like the following to compartmentalize your code inside the activity.

@Override
protected void onPostExecute(Bitmap r){
    if (r != null) {
        processListeners(r);
    }
}

protected void processListeners(Object data) {
    for (final AsyncTaskDone l : listeners) l.finished(data);
}

public void addAsyncTaskListener (final AsyncTaskDone l){
    listeners.add(l);
}

Where AsyncTaskListener is an interface with one function called finished implemented in the Activity the same way an onClickListener would be.

chris-tulip
  • 1,840
  • 1
  • 15
  • 22
  • Be careful with this, when it comes to configuration changes of an activity. This is best used from something like a retained fragment. – CommonsWare Sep 17 '12 at 22:34
  • True - for rotation the best solution would be to implement the Loader class instead – chris-tulip Sep 17 '12 at 22:36
  • I would not say that, as the `Loader` framework really only works well for `ContentProviders`, and less well for anything else. – CommonsWare Sep 17 '12 at 22:55
  • I've only been using the Loader class in association with calling web APIs since it allowed for nice data management through initLoader and restartLoader. The initLoader function simply retrieved data from a cache allowing the views to repopulate on rotate. Have I been using this wrong? – chris-tulip Sep 17 '12 at 23:01
  • Quoting the documentation, "They monitor the source of their data and deliver new results when the content changes." If your `Loader` does this, great! If not, and your own code does not need this feature, great! However, it is difficult to create a reusable `Loader` given this limitation. I have written `Loader` implementations for SQLite and `SharedPreferences` that try to honor this portion of the `Loader` contract, and that work turned me off from the `Loader` framework in general. – CommonsWare Sep 17 '12 at 23:04