Android: multiple intentservices or one intentservice with multiple intents?
Asked Answered
W

1

14

I'm a little confused about intentService. The docs say that if you send an intentService multiple tasks (intents) then it will execute them one after the other on one separate thread. My question is - is it possible to have multiple intentService threads at the same time or not? How do you differentiate in the code between creating three different intents on the same intentService (the same thread), or three separate intentServices each with it's own thread and one intent each to execute?

In other words, when you perform the command startService(intent) are you putting the intent in a single queue or does it start a new queue every time?

Intent someIntent1 = new Intent(this, myIntentService.class);
Intent someIntent2 = new Intent(this, myIntentService.class);
Intent someIntent3 = new Intent(this, myIntentService.class);
startService(someIntent1);
startService(someIntent2);
startService(someIntent3);
Whinstone answered 13/6, 2016 at 17:0 Comment(0)
T
12

1) Is it possible to have multiple intentService threads at the same time or not?

No, each IntentService only has one HandlerThread that it uses to execute requests in the order that "startService" is called. Unless, for some reason you decide to spawn your own Thread/Threads in the IntentService, but that would likely defeat the purpose of using IntentService in the first place. Services of the same manifest declaration i.e. service name=".MyIntentService" (and this is the same for normal Services) run as a singleton within their process, so until the Service is killed the same Service will receive additional start requests.

2) How do you differentiate in the code between creating three different intents on the same IntentService?

To differentiate between requests, use the Intent system as it's intended! Provide different "Actions" for different jobs the service can carry out, and pass along any extras the IntentService needs to run correctly for that particular job as extras in the Intent object you're using to start the Service.

Taxation answered 13/6, 2016 at 17:5 Comment(17)
If I use different intentservices like so: Intent someIntent1 = new Intent(this, myIntentService1.class); Intent someIntent2 = new Intent(this, myIntentService2.class); Intent someIntent3 = new Intent(this, myIntentService3.class); startService(someIntent1); startService(someIntent2); startService(someIntent3); do they still run in the same handlerThread?Whinstone
Yes, all requests to startService will hit onHandleIntent() in the order in which startService is called with each intent object. So, basically you're queueing up three "jobs" for the Intent service to run in a queue fashion. Once onHandleIntent() finishes running/or being blocked by the current operation, it'll be hit by the next startService(Intent intent) request that you've queued up. Once all "startService" jobs are finished, the intent service will shut itself down, because it's underlying Handler doesn't have anymore messages to "handle".Taxation
@pskink that's the question really, because if three services create three threads, then there's really no way of "queueing" tasks on the same handlerThread, and if so then I don't understand what the dev docs mean when they talk about this queueing taking place.Whinstone
from the docs: "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."Whinstone
@Whinstone call startService(someIntent1) twice, call startService(someIntent2) four times and add some Log.d inside each onHandleIntent method and you will see how it worksAbiosis
You can also look at the source of IntentService -- it's actually pretty simple. It just requires some knowledge on how Handler's work -- they only Service one "message" on their thread at a time.Taxation
Yes, I understand that they only service one message at a time, simply I was confused as to whether you could create multiple message queues concurrently or notWhinstone
"The only way you could have multiple IntentServices (and this is the same for normal Services), is to run them in separate Processes" -- nonsense.Isaac
@Jon: "I was confused as to whether you could create multiple message queues concurrently or not" -- yes. Each IntentService has its own work queue. Your quote from the docs is referring to a single IntentService, not three separate IntentServices.Isaac
@CommonsWare, how? The first, if already created in the current App process will receive additional messages and run in the previously created Service until the message pool is drained, and then it will be shut down (that's why in the ServiceHandler, after onHandleIntent, the "stopService(int startId)" call is called. At that point, another instance will be created. At least this is my understanding, so if it's different something more than "nonsense" would be a better comment.Taxation
@Isaac do you mean that it's possible to have multiple intentServices in the same process, or that it's impossible to have multiple intentServices even if you use different processes (i.e. one single queue for the entire system)?Whinstone
@Whinstone as i said, if you have 3 separate IntentServices then you have 3 HandlerThreads but what if you want another message type to request? would you like to add just another IntentService? it makes no sense imhoAbiosis
@Submersed: "how?" -- by creating more than one subclass of IntentService. "The first, if already created in the current App process will receive additional messages" -- only for startService() calls with an Intent identifying that IntentService. Each IntentService has its own HandlerThread, which in turn has its own MessageQueue. While an individual Service class is effectively a singleton, separate Service classes have independent lifecycles, just as separate Activity instances do. And they can all be in one process.Isaac
Edited for clarification. My wording was apparently off.Taxation
@Jon: "do you mean that it's possible to have multiple intentServices in the same process" -- yes, if they are separate implementations. In your question, you appear to be starting the same service (myIntentService) three times. That will create one instance of the service, which will process the three queued commands sequentially. If, OTOH, you have three separate IntentService subclasses (e.g., myIntentService, myIntentService2, myIntentService3), and you call startService() once on each of those, they will run in parallel.Isaac
@Submersed: I would expect some sort of build error if you try having more than one <service> element pointing to the same component, even if you use different android:process values. After all, Android cannot distinguish the two when an explicit Intent is used.Isaac
@Isaac Yea, me too. I simplified further, since that portion wasn't really necessary to get the point across, just the fact that Services are singletons within their process -- which is really all I was trying to say there. I'm interested in testing out a few use cases now though :)Taxation

© 2022 - 2024 — McMap. All rights reserved.