这建立在earlier question之上,这是一个PoC。
上图显示了我的应用程序中工作的基本设置。
在实时应用中,我在IntentService
的{{1}}方法中调用onOptionsItemSelected()
,如下所示:
Fragment
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
...
...
Intent myServiceIntent = new Intent(getActivity(), MyService.class);
getActivity().startService(myServiceIntent);
...
...
}
从云中下载数据并将其保存到本地MyService
数据库中。接下来,同一SQLite
中的AsyncTask
消费数据以更新另一个Fragment
。关键是,Fragment
应在 AsyncTask
完成后开始doInBackground()
。
PoC与MyService
合作正常,显示Service
并通过ProgressBar
保持UI不断更新中间结果。请注意BroadcastReceiver
来自Service
,但在真实应用中,来自AppCompatActivity
。完全相同的设置失败,没有Fragment
,没有临时更新。在 ProgressBar
完成后,来自BroadcastReceiver
的日志消息显示。
然后是问题,
AsyncTask
IntentService
阻止用户界面AsyncTask
get()
? PoC答案是否定的,但在我的实时应用程序中,临时进度更新失败。AsyncTask
如何等待IntentService
完成?BroadcastReceiver
完成后,AsyncTask
显示的日志才会显示? 请注意,我见过this answer,但不幸的是,没有一个真的适合我。
非常感谢提前!
答案 0 :(得分:1)
IntentServices本质上阻止了UI,比如AsyncTask get()?
不,他们没有,这是IntentService在后台做事的重点
AsyncTask如何等待IntentService完成?
有几种方法,但一种简单的方法是在您的活动中使用BroadcastReceiver来保存您的片段并让您的活动触发片段/更新。记住一个片段不应该与另一个片段交谈,你的活动应该是片段之间的委托信息。
为什么您的BroadcastReceiver无法在您的真实应用中运行我无法回答您提供的信息,当您进行更改时可能会遗漏某些内容。我一直使用带有IntentServices的BroadcastReceivers而没有任何问题
答案 1 :(得分:0)
感谢@tyczj提供清晰简洁的答案!
刚刚正式完成......
为什么仅在
BroadcastReceiver
完成后才显示AsyncTasks
中的日志?
虽然模糊不清,但这是我的错误,呃。 (仅)调试显示。
这是一种常见的情况,是否有最佳做法可以克服这个问题?
恕我直言的最佳做法是 练习 。然而,这些是我理解的(难点):
IntentService
超过AsyncTask
,背景工作时间超过5秒LocalBroadcastManager
与BroadcastReceiver
一起显示来自IntentService
的进度更新,并让其他更快的后台线程等待。