如何在Android中高效地管理多个异步任务?

时间:2022-06-15 21:02:11

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.

我有一个场景,我需要在服务器上做6个http调用来获取6个不同项目的数据。这些服务器调用不能组合在一起,它们应该是这样的。如果你需要谷歌的报价信息,那么发送一个请求到服务器请求谷歌的报价信息。接下来,如果您需要yahoo,那么您将发起另一个http调用,等等。

Here is the situation:

这是这句话的语境是:

  1. Now my end user wants to compare 6 different companies.
  2. 现在我的终端用户想要比较6个不同的公司。
  3. As I mentioned its un-avoidable for me to make 6 http calls for which I do using 6 Async Tasks.
  4. 正如我所提到的,对我来说,使用6个异步任务进行6个http调用是不可避免的。
  5. As I get each one of the Async task response I will refresh the UI with new data.
  6. 当我获得每个异步任务响应时,我将使用新的数据刷新UI。
  7. Its a bad UI experience if I refresh the UI 6 times in a very short period of time.
  8. 如果我在很短的时间内刷新UI 6次,那将是一种糟糕的UI体验。
  9. Its give a flickering effect to my UI which is not desired.
  10. 它会给我的UI带来不希望的闪烁效果。

My Question:

我的问题:

  1. How can I hold-off from refreshing the UI until I get all the 6 Async Task responses?
  2. 如何在获得所有6个异步任务响应之前,不刷新UI ?
  3. I understand each task is independent of each other. Should I run a while loop and wait until I get all the responses?
  4. 我知道每个任务都是相互独立的。我应该运行一个while循环并等待所有的响应吗?
  5. 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.
  6. 是否有更好的方法来做这个,而不是一个while循环,因为如果任何一个调用没有响应,那么我将永远等待。

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

注意:我想Android 1.6+可以并行执行异步任务。

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

这更像是一个设计问题,我希望能得到任何帮助。

Thanks in advance

谢谢提前

4 个解决方案

#1


4  

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

您可以创建一个AsyncTask pool对象,该对象允许您对“批处理”http调用进行欺骗。

  1. create an Observable collection of AsyncTasks, i'll refer to this collection as your Pool
  2. 创建一个可观察的异步任务集合,我将该集合作为您的池
  3. your Activity creates the AsyncTasks (but not execute yet) and adds them to the Pool
  4. 您的活动创建了AsyncTasks(但还没有执行)并将它们添加到池中
  5. Activity registers itself as an observer of the Pool
  6. 活动将自己注册为池的观察者。
  7. Activity tells Pool to execute, Pool in turn calls execute on each of its Tasks
  8. 活动告诉Pool to execute, Pool依次调用执行它的每个任务
  9. 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'
  10. 当任务完成时(对于成功和失败),它们将响应数据存储在池中,池将任务标记为“完成”
  11. Once all Tasks are marked as complete, Pool notifies the listening Activity
  12. 一旦所有任务被标记为完成,Pool将通知侦听活动

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.

您必须弄清楚AsyncTasks是如何告诉池它们已经完成的。也许简单地有一个AsyncTask的实现,它在构造函数中接受一个池,这样任务就有了对池的引用。

#2


1  

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.
  • 对由您的活动创建的处理程序执行sendEmptyMessageDelayed(),例如,每500ms,该处理程序刷新来自网络任务的数据,并继续这样做,直到处理所有的网络结果。
  • 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.

如果是我的话,我很可能会和教练一起去。总之,让您的网络任务将数据存储在某个中间存储中。向处理程序发送延迟的消息,并在handleMessage()中检查中间存储中的数据并发布更新的结果。如果有未完成的结果,再次发布延迟消息。

#3


1  

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

我发现这个解决方案更适合我的问题。这个链接描述了建立这个关系的几种方法。1。ExecutorService 2。ExecutoreService和CountDownLatch

ExecutoreService and CountDownLatch

ExecutoreService和CountDownLatch

#4


1  

just stabbing in the dark here, but you have:

只是在黑暗中刺,但你有:

  • 1x main UI thread
  • 1 x主UI线程
  • 6x background asynchtasks which have: 6x methods to execute in background 6x methods to return data to UI (foreground)
  • 6x后台异步任务:在后台6x方法中执行6x方法,将数据返回到UI(前台)

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:

为什么不在UI线程中设置一个名为“完成任务”的公共作用域变量呢?

  • increments finishedTasks

    增量finishedTasks

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

    如果完成任务= 6,那么运行一个公共方法来更新UI

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

然后,它将在所有后台任务完成时更新UI。

#1


4  

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

您可以创建一个AsyncTask pool对象,该对象允许您对“批处理”http调用进行欺骗。

  1. create an Observable collection of AsyncTasks, i'll refer to this collection as your Pool
  2. 创建一个可观察的异步任务集合,我将该集合作为您的池
  3. your Activity creates the AsyncTasks (but not execute yet) and adds them to the Pool
  4. 您的活动创建了AsyncTasks(但还没有执行)并将它们添加到池中
  5. Activity registers itself as an observer of the Pool
  6. 活动将自己注册为池的观察者。
  7. Activity tells Pool to execute, Pool in turn calls execute on each of its Tasks
  8. 活动告诉Pool to execute, Pool依次调用执行它的每个任务
  9. 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'
  10. 当任务完成时(对于成功和失败),它们将响应数据存储在池中,池将任务标记为“完成”
  11. Once all Tasks are marked as complete, Pool notifies the listening Activity
  12. 一旦所有任务被标记为完成,Pool将通知侦听活动

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.

您必须弄清楚AsyncTasks是如何告诉池它们已经完成的。也许简单地有一个AsyncTask的实现,它在构造函数中接受一个池,这样任务就有了对池的引用。

#2


1  

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.
  • 对由您的活动创建的处理程序执行sendEmptyMessageDelayed(),例如,每500ms,该处理程序刷新来自网络任务的数据,并继续这样做,直到处理所有的网络结果。
  • 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.

如果是我的话,我很可能会和教练一起去。总之,让您的网络任务将数据存储在某个中间存储中。向处理程序发送延迟的消息,并在handleMessage()中检查中间存储中的数据并发布更新的结果。如果有未完成的结果,再次发布延迟消息。

#3


1  

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

我发现这个解决方案更适合我的问题。这个链接描述了建立这个关系的几种方法。1。ExecutorService 2。ExecutoreService和CountDownLatch

ExecutoreService and CountDownLatch

ExecutoreService和CountDownLatch

#4


1  

just stabbing in the dark here, but you have:

只是在黑暗中刺,但你有:

  • 1x main UI thread
  • 1 x主UI线程
  • 6x background asynchtasks which have: 6x methods to execute in background 6x methods to return data to UI (foreground)
  • 6x后台异步任务:在后台6x方法中执行6x方法,将数据返回到UI(前台)

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:

为什么不在UI线程中设置一个名为“完成任务”的公共作用域变量呢?

  • increments finishedTasks

    增量finishedTasks

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

    如果完成任务= 6,那么运行一个公共方法来更新UI

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

然后,它将在所有后台任务完成时更新UI。