简体   繁体   English

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

[英]How to manage multiple Async Tasks efficiently in Android

I have scenario where I will have to make six http calls to my server to get the data for six different items. 我有这样的场景,我将不得不对我的服务器进行六次http调用,以获取六个不同项目的数据。 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. 例如:如果您需要GOOGLE的报价信息,请向服务器发送请求谷歌报价信息的请求。 Next if you need yahoo's then you initiate another http call and so on. 接下来,如果你需要雅虎,那么你发起另一个http呼叫,依此类推。

Here is the situation: 情况如下:

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

My Question: 我的问题:

  1. How can I hold-off from refreshing the UI until I get all the 6 Async Task responses? 在获得所有6个异步任务响应之前,如何暂停刷新UI?
  2. I understand each task is independent of each other. 我理解每项任务都是相互独立的。 Should I run a while loop and wait until I get all the responses? 我应该运行一个while循环并等到我收到所有响应吗?
  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. 有没有更好的方法来做这个而不是一个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 提前致谢

You could make a AsyncTask pool object that allows you to spoof a 'batch' http call. 您可以创建一个AsyncTask池对象,允许您欺骗“批量”http调用。

  1. create an Observable collection of AsyncTasks, i'll refer to this collection as your Pool 创建一个AsservTasks的Observable集合,我将这个集合称为您的池
  2. your Activity creates the AsyncTasks (but not execute yet) and adds them to the Pool 您的Activity创建AsyncTasks(但尚未执行)并将它们添加到池中
  3. Activity registers itself as an observer of the Pool Activity将自己注册为Pool的观察者
  4. Activity tells Pool to execute, Pool in turn calls execute on each of its Tasks Activity告诉Pool执行,Pool依次调用每个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 将所有任务标记为完成后,Pool会通知侦听活动

General idea is for the Pool to know how many Tasks and pending, and to store the aggregate data of completed calls. 一般的想法是让Pool知道有多少任务和待处理,以及存储已完成调用的聚合数据。 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. 你必须弄清楚AsyncTasks如何告诉Pool他们已经完成了。 Maybe simply have an implementation of AsyncTask that takes a Pool on its constructor so that the Tasks have a reference to the Pool. 也许只是简单地使用AsyncTask的实现,它在其构造函数上使用Pool,以便Tasks具有对Pool的引用。

just stabbing in the dark here, but you have: 只是在黑暗中刺伤,但你有:

  • 1x main UI thread 1x主UI线程
  • 6x background asynchtasks which have: 6x methods to execute in background 6x methods to return data to UI (foreground) 6x背景asynchtasks有: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线程中没有公共范围的变量称为“ finishedTasks ”,那么每个6x返回数据线程中的相同方法:

  • increments finishedTasks 增量完成任务

  • if finishedTasks == 6 then run 1 public method to do the update of the UI 如果finishedTasks == 6则运行1个公共方法来更新UI

then it would update the UI on all background asychtasks completing. 然后它将更新所有背景asychtasks完成的用户界面。

There are many ways you could handle this: 有很多方法可以解决这个问题:

  • Another AsyncTask that aggregates the responses from the network tasks. 另一个AsyncTask聚合来自网络任务的响应。
  • 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. 每个(比如说500ms sendEmptyMessageDelayed()执行一个sendEmptyMessageDelayed()到一个由Activity创建的Handler ,它刷新从网络任务进入的数据,并继续这样做,直到处理完所有的网络结果。
  • A Thread that performs the aggregation. 执行聚合的线程。

Were it me, I'd probably go with the Handler . 如果是我,我可能会选择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. 将延迟消息发送到处理程序,并在handleMessage()检查中间存储中的数据并发布更新结果。 If there are results outstanding, post the delayed message again. 如果结果未完成,请再次发布延迟消息。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM