8

I am using AsyncTask in a lot of places without issues.

Now with Honeycomb, all network i/o needs to be in thread separate from the UI thread, which in a lot of cases needs AsyncTasks in places, where before a synchronous network connection was well suited (Honeycomb will throw an Exception for any network i/o on the main/ui thread).

Now I would basically like to get something like Object result = MyAsyncTask().execute() are there good patterns for this?

I've found AsyncTask Android - Design Pattern and Return Values which makes sense and is also how GWT does things, but somehow this sounds like wagging the dog by the tail (and then it may just be me who's brain needs some more twisting).

Community
  • 1
  • 1
Heiko Rupp
  • 30,426
  • 13
  • 82
  • 119

3 Answers3

13

Yup. You're close. Try

Object result = MyAsyncTask().execute().get();
Tyler Collier
  • 11,489
  • 9
  • 73
  • 80
  • Thanks - that was exactly what I was looking for - how could I have missed that first. For some parts the GWT pattern is quite nice, but this ....get() makes a lot of sense when it is required until the async taks has finished. – Heiko Rupp Aug 06 '11 at 14:53
  • 7
    Just food for thought and for others stumbling across this answer, calling execute().get() from the UI thread is virtually the same as running the operation on the UI thread. Although this avoids raising the Exception for network calls on the main thread, it doesn't avoid the implications of the action. Your UI thread will block until the network action is complete. You could potentially cause a deadlock by having a postExecute method because that method will wait for the main thread to become available. IMHO you are presenting an anti-pattern for AsyncTasks. – Nick Campion Feb 02 '12 at 21:56
4

I'm sure that you're not wanting to perform a synchronous network transaction on the UI thread, right?

The pattern that I use is to hold state in the Activity (which implements a receiver), then call AsycTask which performs a callback to your activity in onPostExecute() (i.e. fire an Intent which your activity is listening for). Your activity can then update the state according to extras in the intent, and continue processing. It's basically a state machine held in your Activity which performs your login and other functions. All of the network I/O stuff is performed in AsycTask instances which cause the state to be updated as they complete.

Mark Allison
  • 21,839
  • 8
  • 47
  • 46
  • Yes, not on the UI thread. Before HC this was possible (and there are places, where it makes sense), but HC will throw an Exception for any network calls on the UI thread. – Heiko Rupp Jun 13 '11 at 09:54
1

If you just want to block your thread, while other thread does the job, you could consider writing your own task abstraction. I am thinking of something like

public class MyTask <T>  {
    // define executor here
    public T execute(Callable<T> c) {
        Future<T> t = executor.submit(c);
        return t.get();
    }
 }
Alex Gitelman
  • 24,429
  • 7
  • 52
  • 49