【问题标题】:Synchronizing between IntentServices and AsyncTasksIntentServices 和 AsyncTasks 之间的同步
【发布时间】:2016-04-09 17:49:17
【问题描述】:

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

上图显示了我的应用中工作的基本设置。

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

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

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

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

那么问题是,

  • IntentServices 是否天生会阻止 UI,例如 AsyncTask get()? PoC 的答案是否定的,但在我的实时应用中,临时进度更新失败。
  • AsyncTask 如何等到IntentService 完成?
  • 为什么BroadcastReceiver 中的日志只有在AsyncTasks 完成后才显示
  • 这种情况很常见,是否有最佳实践来克服这种情况?

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

请注意,我见过this answer 等,但不幸的是,没有一个真正适合我。

提前非常感谢!

【问题讨论】:

    标签: android android-fragments android-asynctask intentservice


    【解决方案1】:

    IntentServices 是否天生会阻塞 UI,例如 AsyncTask get()?

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

    AsyncTask 如何等到 IntentService 完成?

    有几种方法,但一种简单的方法是在您的活动中使用广播接收器来保存您的片段并让您的活动触发片段更新。请记住,片段不应该与另一个片段对话,您的活动应该是片段之间的委托信息。

    为什么您的 BroadcastReceiver 在您的实际应用程序中不起作用我一直使用带有 IntentServices 的 BroadcastReceivers 没有任何问题

    【讨论】:

    • 谢谢@tyczj!你说,“记住一个片段不应该与另一个片段对话”——我的BroadcastReceivers 和服务启动器在一个片段中,所以兄弟片段正在说话。这可能是我没有看到临时进度更新的原因吗?将BroadcastReceivers 和服务启动器移动到主机Activity 是否值得?
    • 虽然我猜您可以考虑使用广播接收器与 2 个片段对话,但这并不是我真正的意思。我在说的是一个片段直接引用了另一个片段,这是不好的。自 IMO 以来,我个人会将您的广播接收器移动到您的控股活动中,这将使代码更加简洁
    【解决方案2】:

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

    只是为了正式完成……

    为什么BroadcastReceiver 中的日志只有在AsyncTasks 完成后才会显示?

    虽然晦涩难懂,但这很大程度上是我的错误,呵呵。 (仅)调试显示。

    这种情况很常见,是否有最佳实践来克服这种情况?

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-21
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 2021-12-04
      相关资源
      最近更新 更多