Can starting an intent service several times in quick succession cause unnecessary extras?

We see a problem when one of our intent services unexpectedly retrieves a null String extra for some of our users. We were unable to reproduce this, and we do not know whether it is random or sequential on the affected user device. There does not seem to be a correlation between the affected users and the type of device or version of Android.

I extend the IntentService and implement the handleIntent method as follows:

 @Override public void handleIntent(Intent intent) { String action = intent.getAction(); if (action.Equals(ACTION_MARK_UNREAD)) { String messageKey = intent.getStringExtra(EXTRA_MESSAGE_KEY); // messageKey is null for some users } } 

With fields:

 public static final String ACTION_MARK_UNREAD = "com.myapp.action.MARK_UNREAD"; public static final String EXTRA_MESSAGE_KEY = "extraMessageKey"; 

In the fragment, we start this service in quick succession 6 times:

  for (int i = 0; i < 6; i++) { Intent i = new Intent(MyIntentService.ACTION_MARK_UNREAD); i = i.setClass(mContext, MyIntentService.class); i.putExtra(MyIntentService.EXTRA_MESSAGE_KEY, i.toString()); mContext.startService(i); } 

Any ideas on which the service will fetch null for messageKey extra?

We have other areas in the application that start the same service, and we cannot determine which one it arises from when this situation occurs. However, looking at the magazines, it seems, from this fragment I mentioned. Logs show that the client’s timestamp when null occurs a few seconds after the previous occurrence. This may be due to the fact that the service queue is moving slowly, or my assumption may be incorrect.

+7
android android-intent
source share
2 answers

My first guess is the compiler problem, which many others commented on, and I see some other errors in your examples, for example Equals with upper E.

But, given your code as an example, I tested this approach a lot, and the first thing I conclude does not matter if your calls are inside a Fragment or an Activity because of the Context from the Fragment matches the parent Activity .

IntentService documentation, we can read that:

All requests are processed on one workflow - they can be accepted as needed (and will not block the main application cycle), but only one request will be processed at a time.

Here: http://developer.android.com/reference/android/app/IntentService.html

So, we can conclude that all your X-requests will be processed one at a time one by one.

Another piece of Android documentation about IntentService we can read that:

Since most running services do not need to process multiple requests at the same time (which can be a dangerous multi-threaded scenario), this is probably best if you are implementing your service using the IntentService Class.

Here: http://developer.android.com/guide/components/services.html#ExtendingIntentService

So with this information, you may think that IntentService is the approach you need. Correctly?

Here you can find out how only Service distributed: http://developer.android.com/guide/components/services.html#ExtendingService

Having finished, below I insert the code I made to test your approach.

The main Activity class is MainActivity .

 public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); for (int i = 0; i < 10; i++) { Intent intent = new Intent(MyIntentService.MY_ACTION); intent.setClass(this, MyIntentService.class); intent.putExtra(MyIntentService.EXTRA, UUID.randomUUID().toString()); startService(intent); } } } 

IntentService MyIntentService .

 public class MyIntentService extends IntentService { public static final String MY_ACTION = "my.app.namespace.action.myaction"; public static final String EXTRA = "my_extra"; public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { String action = intent.getAction(); if (action.equals(MY_ACTION)) { String messageKey = intent.getStringExtra(EXTRA); Log.i(EXTRA, messageKey); } } } 

And Log Out.

 my_extra﹕ b6faeb0a-29fa-442b-b87e-9c7a5f8c35d7 my_extra﹕ 88076250-d455-4084-af5f-c560ba6d5570 my_extra﹕ 21339466-25ab-4aaa-aadd-344555c4c2df my_extra﹕ 2f935a93-465b-4648-a3cc-60f0c9cc67a4 my_extra﹕ 128653d1-d6af-499f-8725-78158e2e7190 my_extra﹕ e453ae7b-e21a-41fe-bf9c-f45ccfd13edf my_extra﹕ 2e3fc6aa-e425-41dd-a584-8ab056fb906d my_extra﹕ a8d90d53-c6cd-4d15-84f9-4064d6972de9 my_extra﹕ 721dd17b-b977-4029-ada3-5999f0eb36e7 my_extra﹕ e83d3277-adc8-47a8-a246-6cd7f6f2735d 
+2
source share

Will you try?

 for (int y = 0; y < 6; y++) { Intent i = new Intent(MyIntentService.ACTION_MARK_UNREAD); i = i.setClass(mContext, MyIntentService.class); i.putExtra(MyIntentService.EXTRA_MESSAGE_KEY, y.toString()); mContext.startService(i); } 

There may be a problem with the compiler ...

+1
source share

All Articles