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

发布于 2025-01-04 08:47:01 字数 644 浏览 1 评论 0原文

我有一个场景,我必须对我的服务器进行六个 http 调用才能获取六个不同项目的数据。这些服务器调用无法组合,它们本来就是这样的。例如:如果您需要 GOOGLE 的报价信息,则向服务器发送请求,请求 google 的报价信息。接下来,如果您需要 yahoo 的,那么您将发起另一个 http 调用,依此类推。

情况是这样的:

  1. 现在我的最终用户想要比较 6 家不同的公司。
  2. 正如我提到的,我使用 6 个异步任务进行 6 个 http 调用是不可避免的。
  3. 当我收到每个异步任务响应时,我将使用新数据刷新 UI。
  4. 如果我在很短的时间内刷新 UI 6 次,那么 UI 体验会很糟糕。
  5. 它给我的用户界面带来了闪烁的效果,这是不希望的。

我的问题:

  1. 如何推迟刷新 UI,直到获得所有 6 个异步任务响应?
  2. 我了解每项任务都是相互独立的。我应该运行 while 循环并等待直到收到所有响应吗?
  3. 有没有比 while 循环更好的方法来做到这一点,因为如果任何一个调用没有响应,那么我将永远等待。

注意:我猜 Android 1.6+ 确实并行执行异步任务。

这更多的是一个设计问题,我将不胜感激对此的任何帮助。

提前致谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

巷子口的你 2025-01-11 08:47:01

您可以创建一个 AsyncTask 池对象,该对象允许您欺骗“批量”http 调用。

  1. 创建 AsyncTasks 的 Observable 集合,我将将此集合称为您的池,
  2. 您的 Activity 创建 AsyncTasks(但尚未执行)并将它们添加到池中,
  3. 活动将自身注册为池的观察者,
  4. 活动告诉池执行,池依次调用每个任务的执行
  5. 当任务完成(成功和失败)时,它们将响应数据存储在池中,并且池将任务标记为“完成”
  6. 一旦所有任务都标记为完成,池会通知倾听活动

池的总体思路是了解有多少任务和待处理任务,并存储已完成调用的聚合数据。全部完成后,通知观察Activity并传​​回所有数据。

您必须弄清楚 AsyncTasks 如何告诉池它们已完成。也许只是有一个 AsyncTask 的实现,它在其构造函数上采用一个 Pool,以便任务可以引用该 Pool。

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.

几度春秋 2025-01-11 08:47:01

有很多方法可以处理这个问题:

  • 另一个聚合来自网络任务的响应的 AsyncTask。
  • 每隔 500 毫秒执行一次 sendEmptyMessageDelayed() 到由 Activity 创建的 Handler,刷新从网络任务传入的数据并继续这样做,直到处理完所有网络结果。
  • 执行聚合的线程。

如果是我,我可能会选择 Handler。总而言之,让您的网络任务将数据存储在某些中间存储中。将延迟消息发送到处理程序,并在 handleMessage() 中检查中间存储中的数据并发布更新的结果。如果结果尚未完成,请再次发布延迟的消息。

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.

晨光如昨 2025-01-11 08:47:01

我发现这个解决方案更适合我的问题。
此链接描述了建立此目的的几种方法。
1.执行者服务
2. ExecutoreService 和 CountDownLatch

ExecutoreService 和 CountDownLatch

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

硪扪都還晓 2025-01-11 08:47:01

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

  • 1x 主 UI 线程
  • 6x 后台异步任务,其中有: 6x 在后台执行的方法
    将数据返回到 UI(前台)的 6x 方法

为什么不在 UI 线程中拥有一个公共范围的变量(称为“finishedTasks”),然后在 6x 返回数据线程中的每个线程中使用相同的方法:

  • < p>incrementsfinishedTasks

  • 如果finishedTasks == 6则运行1个公共方法来更新UI

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文