My application makes its web service calls from an IntentService. Each Intent is effectively a web service call that needs to take place.
As you know, an IntentService queues Intents; so only 1 web service call will be taking place at any given time. This is actually desired behavior.
However, this does present a problem. Suppose my app queues up 5 Intents in this IntentService. Say the user ends up on a screen that maybe holds up the UI while some data is retrieved from a web service. If the Intent for this web service is put on the back of the queue, it could be a long while before the web service is called, holding the user up for an unacceptable amount of time.
Since I can’t inject Intents to the front of an IntentService’s queue (as far as I know), I’ve decided to create a second IntentService for calls that require immediate execution. Since I only want 1 call hitting my services at any given time, I’ve wrapped a mutex around the actual Http code. So, in this case, the Intent would execute right away (because it’s in a different IntentService), but loop on the mutex until whatever call in the other IntentService is finished.
This works good for me; I’m fine with all of it.
Here is my question:
Theoretically, the new IntentService could queue up, too. Because of the application workflow, this is unlikely to happen, but it’s theoretically possible. If this is the case, I’d like the new IntentService to finish before the original IntentService resumes again. My idea for doing this is locking/unlocking a new mutex in the create and destroy methods of the new IntentService. The same mutex will also be locked/unlocked at the beginning and end of the onHandleIntent method of the old IntentService. However, I’m concerned about what ramifications locking a mutex in the create of an IntentService will have, holding up its creation (presumably, super.create will be called before the lock). Will Intents still be able to queue up? Are there any other pitfalls to doing this?
Not with the standard implementation. However,
IntentServiceis not a big class. You could clone it and replace theHandler-based system it uses today with aPriorityBlockingQueue.Besides it scaring the crap out of me, in terms of possible deadlocks?
You might look at
ReentrantReadWriteLockor something along those lines, instead of theMutexpair. While technically yours is not a “read” vs. “write” scenario, you can think of “read” and “write” as simply being two priorities. There are ways to configure such a lock to favor “writes”, so your 2ndIntentServicewould be the “write” and your 1stIntentServicewould be the “read”.But I’d really look to replace
IntentServicewith a workalike that has the characteristics you seek, rather than trying to get twoIntentServicesto work together.