【问题标题】:Android: Understanding using one IntentService with multiple actionsAndroid:理解使用一个 IntentService 和多个操作
【发布时间】:2013-02-17 19:21:34
【问题描述】:

在特定活动流​​下,意图未传递到 IntentService 时遇到问题:这是场景:

  1. 考虑 3 个活动,Home、B 和 C。C 有 2 个片段 CF1 和 CF2。
  2. B、CF1 和 CF2 使用相同的 IntentService 类,但操作不同。
  3. IntentService 使用 startService(Intent) 启动。 (getActivity().startService(Intent) 用于 Fragments)
  4. 无论 IntentService 在哪里启动,如果它在 Activity/Fragment 的 onStop() 中运行,我会确保它使用 stopService(intent) 停止。
  5. 如果活动流程是 Home -> C -> CF1 - >CF2,则一切正常。
  6. 如果活动流程是 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


【解决方案1】:

我的理解是......如果服务是第一次运行,onStartCommand 被调用(我们不应该为 IntentService 处理)。如果服务已在运行,则每次后续调用 startService 都会调用 onHandleIntent。

没有。每次调用 startService() 都会调用 onStartCommand()。每次对IntentService 进行的startService() 调用都会调用onHandleIntent(),除非您在onStartCommand() 中执行某些操作来改变正常行为。

IntentService 使用 startService(Intent) 启动。

您使用startService()IntentService 发送命令。

无论 IntentService 在哪里启动,我都会使用 stopService(intent) 确保它停止

这是一个非常糟糕的主意。 IntentService 将在处理完所有startService() 调用后自行停止,如the documentation 中所述:

IntentService 将接收 Intent,启动工作线程,并酌情停止服务。

【讨论】:

  • 就像@G.BlakeMeike 你说的那样,我尝试删除 stopService 并且它起作用了。但是,当用户离开正在运行 IntentService 的活动时,我再次不确定正确的方法是什么。你说这是个坏主意,如果用户离开活动,我们不应该停止服务吗?
  • @Prasanna:使用IntentService 背后的要点是因为您希望“如果用户正在离开活动”继续工作。如果您不希望这样,请不要使用IntentService - 只需使用线程即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 2012-07-01
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多