How to manage multiple Async Tasks efficiently in

2020-01-31 02:21发布

I have scenario where I will have to make six http calls to my server to get the data for six different items. These server calls cant be combined and they are meant to be that way. Eg: If you need quote info for GOOGLE then send a request to server requesting for google's quote info. Next if you need yahoo's then you initiate another http call and so on.

Here is the situation:

  1. Now my end user wants to compare 6 different companies.
  2. As I mentioned its un-avoidable for me to make 6 http calls for which I do using 6 Async Tasks.
  3. As I get each one of the Async task response I will refresh the UI with new data.
  4. Its a bad UI experience if I refresh the UI 6 times in a very short period of time.
  5. Its give a flickering effect to my UI which is not desired.

My Question:

  1. How can I hold-off from refreshing the UI until I get all the 6 Async Task responses?
  2. I understand each task is independent of each other. Should I run a while loop and wait until I get all the responses?
  3. Is there a better way to do this rather than a while loop because if any one of the call doesn't respond then I will stuck waiting forever.

Note: I guess Android 1.6+ do execute Async tasks in parallel.

This is more of a design question and I would appreciate any help on this.

Thanks in advance

4条回答
看我几分像从前
2楼-- · 2020-01-31 02:45

There are many ways you could handle this:

  • Another AsyncTask that aggregates the responses from the network tasks.
  • Perform a sendEmptyMessageDelayed() every, say, 500ms to a Handler created by your Activity that refreshes the data that has come in from the network tasks and continues to do so until all of the networking results are dealt with.
  • A Thread that performs the aggregation.

Were it me, I'd probably go with the Handler. To sum up, have your network tasks store the data in some intermediate storage. Send delayed messages to a handler and, within the handleMessage() check for data in the intermediate storage and post updated results. If there are results outstanding, post the delayed message again.

查看更多
走好不送
3楼-- · 2020-01-31 02:45

just stabbing in the dark here, but you have:

  • 1x main UI thread
  • 6x background asynchtasks which have: 6x methods to execute in background 6x methods to return data to UI (foreground)

why not have a variable of public scope in the UI thread say called "finishedTasks", then the same method in each of the 6x return data threads that:

  • increments finishedTasks

  • if finishedTasks == 6 then run 1 public method to do the update of the UI

then it would update the UI on all background asychtasks completing.

查看更多
Evening l夕情丶
4楼-- · 2020-01-31 02:47

I found this solution more appropriate to my problem. This link describes a couple of ways of establishing this. 1. ExecutorService 2. ExecutoreService and CountDownLatch

ExecutoreService and CountDownLatch

查看更多
时光不老,我们不散
5楼-- · 2020-01-31 02:53

You could make a AsyncTask pool object that allows you to spoof a 'batch' http call.

  1. create an Observable collection of AsyncTasks, i'll refer to this collection as your Pool
  2. your Activity creates the AsyncTasks (but not execute yet) and adds them to the Pool
  3. Activity registers itself as an observer of the Pool
  4. Activity tells Pool to execute, Pool in turn calls execute on each of its Tasks
  5. When tasks complete (for both success and fail), they store the response data in the Pool, and the Pool marks the Task as being 'complete'
  6. Once all Tasks are marked as complete, Pool notifies the listening Activity

General idea is for the Pool to know how many Tasks and pending, and to store the aggregate data of completed calls. Once all are finished, notify the observing Activity and pass back all the data.

You'll have to work out how the AsyncTasks tell the Pool that they are finished. Maybe simply have an implementation of AsyncTask that takes a Pool on its constructor so that the Tasks have a reference to the Pool.

查看更多
登录 后发表回答