Java – Synchronize two concurrent network calls in AsyncTask

Synchronize two concurrent network calls in AsyncTask… here is a solution to the problem.

Synchronize two concurrent network calls in AsyncTask

I’m trying to make multiple concurrent HTTP GET calls that may return a response after different times.
Once I have the data, I’ll use it to create a custom adapter for the ListView. Due to the high risk of NullPointerException, I need to make sure that all data exists before trying to create an adapter.
HTTP calls are currently done using AsyncTask, which is convenient for executing them in the background and later calling the UI thread to update the View. But they are not concurrent – each call is executed after the previous call completes.

The issue I’m grappling with is ensuring that all HTTP calls have returned a response before creating the adapter, while still maintaining concurrency.

Is there a way to run multiple concurrent network calls and have the onPostExecute method do what it does after all concurrent HTTP calls are complete?

Or do I need to use more complex threads, locks, etc.?

Solution

If you do not need the response for the HTTP call

A CountDownLatch Tricks that might be done for you. You initialize it with a count and then call countDown(), which returns immediately after each HTTP call. Regarding the onPostExecute side, await() block until countDown() has been called count.

So:

  • Build a constructor for the number of HTTP calls in CountDownLatch and AsyncTask
  • Call latch.countDown() after each HTTP call
  • The thread calls onPostExecute calls latch.await(), which blocks until all of the above threads have completed their HTTP calls

If you do need a reply

The above method works (there is a prior relationship between each countDown() and await() return), but there is another way.

Wrap each HTTP call in Callable<Response> and submit it ExecutorService ; It will immediately give you a Future<Response> which you can then provide to the object that defines the onPostExecute. The method can get the actual response via Response r = future.get(), which will block until the specific callable function completes. If you do this for all HTTP calls, then after you call futureWhatever.get() for each of those futures, you will make sure that the HTTP calls are complete.

One advantage of this approach is that onPostExecute does not have to block until all HTTP calls have completed; It can make progress until the one it needs at the time is completed. For example, if it does:

Future callA = httpA.get();
processCallA(callA);  this could take a while
Future callB = httpB.get();
...

ProcessCallA can then perform its operation even though the HTTP call B is completing as long as the HTTP call A has completed.

Related Problems and Solutions