IntentServices 和 AsyncTasks 之间的同步

Synchronizing between IntentServices and AsyncTasks

这建立在 之上,这是一个 PoC。

上图显示了我的应用程序的基本设置。

在实时应用程序中,我在 FragmentonOptionsItemSelected() 方法中调用 IntentService,如下所示:

@Override
public boolean onOptionsItemSelected(MenuItem item)
{ 
    ...
    ...
    Intent myServiceIntent = new Intent(getActivity(), MyService.class);
    getActivity().startService(myServiceIntent);
    ...
    ...
}

MyService 从云端下载数据并将其保存到本地 SQLite 数据库中。接下来,同一个 Fragment 中的 AsyncTask 消耗数据以更新另一个 Fragment。关键是,AsyncTask 应该在 MyService 完成后开始他们的 doInBackground()

Service 配合得很好,显示 ProgressBar 并保持 UI 通过 BroadcastReceiver 不断更新中间结果。请注意 Service 是从 AppCompatActivity 调用的,但在实际应用中,它是从 Fragment 调用的。完全相同的设置失败,没有 ProgressBar,没有临时更新。来自 BroadcastReceiver 的日志消息显示 AsyncTask 完成后。

接下来的问题是,

请原谅我的冗长,但希望情况清楚。如果有歧义,请发表评论。

请注意,我看过 this answer 等等,但不幸的是 none 真的很适合我。

非常感谢!

Do IntentServices block UI by nature, like AsyncTask get()?

不,他们没有,这就是 IntentService 在后台做事的全部意义

How can an AsyncTask wait till an IntentService has finished?

有几种方法,但一种简单的方法是在您的 activity 中使用 BroadcastReceiver 来保存您的片段并让您的 activity 触发 fragment/s 更新。请记住,一个片段不应与另一个片段对话,您的 activity 应该是片段之间的委托信息。

为什么您的 BroadcastReceiver 在您的真实应用程序中不起作用我无法回答您提供的信息,因为您在更改它时可能只是遗漏了一些东西。我一直将 BroadcastReceivers 与 IntentServices 一起使用,没有任何问题

感谢@tyczj 简洁明了的回答!

正式完成...

Why are logs in the BroadcastReceiver displayed only after the AsyncTasks have finished?

虽然晦涩难懂,但这是我的错误,呃。 (仅)调试显示。

This being such a common situation, is there a best practice to overcome this?

最佳实践恕我直言,实践。然而,这些是我理解的要点(困难的方式):

  • IntentService 超过 AsyncTask 后台工作超过 5 秒
  • LocalBroadcastManagerBroadcastReceiver 以显示来自 IntentService 的进度更新并让其他更快的后台线程等待。