【发布时间】:2013-02-17 19:21:34
【问题描述】:
在特定活动流下,意图未传递到 IntentService 时遇到问题:这是场景:
- 考虑 3 个活动,Home、B 和 C。C 有 2 个片段 CF1 和 CF2。
- B、CF1 和 CF2 使用相同的 IntentService 类,但操作不同。
- IntentService 使用
startService(Intent)启动。 (getActivity().startService(Intent) 用于 Fragments) - 无论 IntentService 在哪里启动,如果它在 Activity/Fragment 的
onStop()中运行,我会确保它使用stopService(intent)停止。 - 如果活动流程是 Home -> C -> CF1 - >CF2,则一切正常。
- 如果活动流程是 Home -> B -> C -> CF1 -> CF2,则在从 CF2 开始服务(Intent)之后,永远不会调用
onHandleIntent。处理 B 和 CF1 意图。对于调试,我尝试在Activity B中等待IntentService完成,然后转到CF1 -> CF2,仍然是同样的问题。 CF1 在启动相同的意图服务时似乎从来没有任何问题。当我尝试为 CF2 创建一个新的IntentService类时,它起作用了。
我的理解是 IntentService 有一个意图队列。如果服务是第一次运行,则调用 onStartCommand(我们不应该为 IntentService 处理)。如果服务已在运行,则每次后续调用 startService 都会调用 onHandleIntent。
显然,我做错了什么,但不清楚是什么。我曾尝试研究其他 stackoverflow 问题,但没有帮助。我使用的代码非常简单:
AndroidManifest.xml
<service android:name=".service.ExampleIntentService" />
活动 B
@Override
public void onCreate(Bundle savedInstanceState)
{
.......
intent = new Intent(getApplicationContext(), ExampleIntentService.class);
intent.setAction(StringConstants.ACTION_B);
serviceRunning = true; //set to false in onReceiveResult
startService(intent);
}
@Override
public void onStop()
{
if(serviceRunning && intent != null)
stopService(intent)
}
片段 CF1
@Override
public void onResume()
{
super.onResume();
intent = new Intent(getActivity(), ExampleIntentService.class);
intent.setAction(StringConstants.ACTION_CF1);
serviceRunning = true; //set to false in onReceiveResult
startService(intent);
}
@Override
public void onStop()
{
if(serviceRunning && intent != null)
stopService(intent)
}
片段CF2的代码完全相同
【问题讨论】:
-
IntentService 不会对意图进行排队。每个入站意图都会调用 startService;所有调用都在服务本地的 Looper 线程上排队。虽然在服务不做任何事情时停止服务是一种很好的做法,但它只是一种优化。我建议您在您的应用正常运行之前停止这样做
-
@G.BlakeMeike 我不明白“不排队意图”和“呼叫在服务本地的 Looper 线程上排队”之间的区别。我将尝试调用 stopService 并查看。但是创建一个单独的intentService会更好吗?我知道这会奏效。编辑:我也不确定为什么片段 CF1 没有出现同样的问题。
-
不同之处在于意图总是传递给 IntentService.startService。 startService 方法将调用加入到本地队列中,从该队列中它们被另一个线程出列,并作为对 onHandleIntent 的调用传递。他们都是。请参阅下面 Mark 的回答:停止调用 stopService。
标签: android intentservice