Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can starting an intent service multiple times in rapid succession cause null extras?

We are seeing an issue where one of our intent services is unexpectedly retrieving a null String extra for some of our users. We haven't been able to reproduce this, and we don't know if it is random or consistent on an affected user's device. There doesn't seem to be a correlation between affected users and device type or Android version.

I am extending IntentService and implementing the handleIntent method like this:

@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 a fragment, we start this service in rapid 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 why the service would retrieve null for the messageKey extra?

We have other areas in the app that start this same service, and we can't identify which one it comes from when this situation happens. However, from looking at logs, it seems to be from this fragment that I mentioned. Logs show that the client timestamp when null happens is several seconds after the previous occurrence. This could be because the service queue is slow to move, or my assumption could be wrong.

like image 969
siger Avatar asked Feb 04 '14 02:02

siger


People also ask

What happens if multiple intents are passed to a started service?

The Service will only run in one instance.

What is the use of Intent service in android?

IntentService is an extension of the Service component class that handles asynchronous requests (expressed as Intent s) on demand. Clients send requests through Context.

Does intent service run in background?

IntentService runs outside the application in a background process, so the process would run even if your application is closed. Google now recommends using the JobIntentService, which is included as part of the support library. On pre-Android O devices, a normal IntentService will be dispatched in the background.

Is IntentService deprecated?

IntentService is deprecated in Android-R / Android-11.


2 Answers

My first guess is the compiler issue that many other commented about and I figure some other errors on your examples like Equals with upper E for example.

But considering your code as an example just, I tested a lot this approach and the first thing that I concludes is no matter if your calls are inside a Fragment or Activity due the Context of Fragment is the same of parent Activity.

Reading the IntentService documentation we can read that:

All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), 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 enqueued one by one.

Another part at Android documentation about IntentService we can read that:

Because most started services don't need to handle multiple requests simultaneously (which can actually be a dangerous multi-threading scenario), it's probably best if you implement your service using the IntentService class.

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

So with that information you can think if IntentService has been the approach that you need. Right?

Here you can learn how extends just a Service: http://developer.android.com/guide/components/services.html#ExtendingService

Finishing, below I'm pasting the code that I made to test your approach.

Main Activity class 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);
        }
    }
}

The 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 the output Log.

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
like image 105
Idemax Avatar answered Oct 09 '22 00:10

Idemax


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

Could be a compiler issue...

like image 1
Mike Docherty Avatar answered Oct 09 '22 00:10

Mike Docherty