【问题标题】:How to manage multiple Async Tasks efficiently in Android如何在 Android 中高效管理多个异步任务
【发布时间】:2012-02-10 01:01:47
【问题描述】:

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

情况如下:

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

我的问题:

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

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

这更像是一个设计问题,如果有任何帮助,我将不胜感激。

提前致谢

【问题讨论】:

    标签: java android http asynchronous android-asynctask


    【解决方案1】:

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

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

    一般的想法是让 Pool 知道有多少 Tasks 和待处理,并存储已完成调用的聚合数据。全部完成后,通知观察 Activity 并传回所有数据。

    您必须弄清楚 AsyncTask 如何告诉池它们已完成。也许只是有一个 AsyncTask 的实现,它在其构造函数中使用一个 Pool,以便 Tasks 具有对 Pool 的引用。

    【讨论】:

      【解决方案2】:

      可以通过多种方式处理此问题:

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

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

      【讨论】:

        【解决方案3】:

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

        ExecutoreService and CountDownLatch

        【讨论】:

        • 我认为这种方法不适合活动,因为 CountDownLatch 等待方法会阻塞,直到所有任务都完成并且不应该阻塞 UI 线程。
        • countDownLatch 位于主 AsyncTask 上,它产生子任务来完成实际工作。所有子任务完成后,主任务合并所有结果并返回 UI 线程
        【解决方案4】:

        只是在这里暗中刺伤,但你有:

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

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

        • 增加finishedTasks

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多