Prasanna
Prasanna

Reputation: 3781

Android: Understanding using one IntentService with multiple actions

I have a problem with intent not getting delivered to an IntentService under a specific activity flow: This is the scenario:

  1. Consider 3 activities, Home, B and C. C has 2 fragments CF1 and CF2.
  2. B, CF1 and CF2 use the same IntentService class but with different actions.
  3. IntentService gets started using startService(Intent). (getActivity().startService(Intent) for Fragments)
  4. Wherever IntentService gets started, I make sure it gets stopped using stopService(intent) if it is running in Activity/Fragment's onStop().
  5. If the activity flow is Home -> C - > CF1 - >CF2, everything works.
  6. If the activity flow is Home -> B - > C -> CF1 - > CF2, then onHandleIntent is never invoked after startService(Intent) from CF2. B and CF1 intents are handled. For debugging, I tried by waiting for IntentService to complete in Activity B and then go to CF1 -> CF2, still the same problem. CF1 never seems to have any problems in starting the same intent service. When I tried creating a new IntentService class for CF2, it worked.

My understanding was that IntentService has a queue for intents. If the service is running for first time , onStartCommand is invoked (which we are not supposed to handle for IntentService). If the service is already running, onHandleIntent is invoked for every subsequent call of startService.

Obviously, I am doing something wrong but not clear as what. I have tried looking into other stackoverflow questions but didn't help. The code I am using is pretty straightforward:

AndroidManifest.xml

<service android:name=".service.ExampleIntentService" />

Activity 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)
}

Fragment 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)
}

The code is exactly the same for fragment, CF2

Upvotes: 3

Views: 6775

Answers (1)

CommonsWare
CommonsWare

Reputation: 1007474

My understanding was... If the service is running for first time , onStartCommand is invoked (which we are not supposed to handle for IntentService). If the service is already running, onHandleIntent is invoked for every subsequent call of startService.

No. onStartCommand() is called for every startService() call. onHandleIntent() is called for every startService() call made to an IntentService, unless you do something in onStartCommand() to change normal behavior.

IntentService gets started using startService(Intent).

You send commands to an IntentService using startService().

Wherever IntentService gets started, I make sure it gets stopped using stopService(intent)

That is an exceptionally bad idea. IntentService will stop itself when all startService() calls have been processed, as mentioned in the documentation:

IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.

Upvotes: 6

Related Questions