My app connects to multiple SPP Bluetooth devices all of which stream data. There are four devices streaming, one at 250 Hz and the rest at 100 Hz. I want to put them in a Service but also want each device to run in a separate Thread. Each Thread must also connect to the SQLite database to insert data in real-time. The devices can connect for long periods and can disconnect at anytime and reconnect at anytime. Once started the app could be running for 24 hours or more and always looking for the availability of already paired devices.
The questions is: is it better performance-wise to do this in a separate Service running multiple Threads (a Thread for each connecting device) or is is better to run a separate IntentService (which will of course runs in its own worker Thread?
I have read many other questions and answers in SO and elsewhere about this and can see the advantages and disadvantages of each approach but I cannot find an answer that specifically answers my question. I am not sure if running multiple Threads in a Service will not still block the main Thread at times. On the other hand I do not think I can run multiple Threads in an IntentService at the same time.
In your intended scenario, IntentService is not a bad idea, but not in the way you are proposing. Based on the documentation:
IntentService is a base class for Services that handle asynchronous
requests (expressed as Intents) on demand. Clients send requests
through startService(Intent) calls; the service is started as needed,
handles each Intent in turn using a worker thread, and stops itself
when it runs out of work.
This "work queue processor" pattern is commonly used to offload tasks
from an application's main thread. The IntentService class exists to
simplify this pattern and take care of the mechanics. To use it,
extend IntentService and implement onHandleIntent(Intent).
IntentService will receive the Intents, launch a worker thread, and
stop the service as appropriate.
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.
So, launching an IntentService for each bluetooth device would mean one or the other would be blocked. Whenever I communicate with multiple sockets (devices), I assign a thread to each socket... this thread is then responsible for connecting to, communicating with, and reconnecting to the socket as necessary. This pattern is the same used in any server program: There's a ClientThread for each connection, which gets spawned by the connection listener.
However, there's a good place for an IntentService as well: It's great to deliver the data to you sqlite database. Place the datum in an intent, send it to your IntentService, and it will open the database (possibly even start a transaction) when it needs to, then post all data, and when it runs out of work, commits the transaction and closes the database. A lot of the necessary plumbing for that is provided by the API.
Related
I want to constantly, without stopping, perform 2-3 kinds of operations from my Service in Android. That is:
check if some hardware is connected and retrieve the data from it every 1 second and save it to the files
send those files a server
perform some calculations
The second job depends on the 1st one.
Note that the Service will have GUI as well if that matters, but the GUI will be used rarely. Most of them time the Service will work in "background" doing what it has to do.
How can I do that? Should there be 3 different threads or what? Or I don't need the thread because it'll be a service?
Any help is appreciated.
If you want to perform all operation in parallel in background then use android service and use ScheduledThreadPoolExecutor class to achieve this.
Otherwise use timer or Executor(with onr thread) inside android service to perform all operation in serial manner.
Let me know, This is helpful for you?
That depends on what type of service you are using, Intent Service or Service.
If you are using Intent Service, then you don't have to worry about creating a new thread, as it itself creates a worker thread.But, just keep in mind that, it takes one care of requests one at a time, in queue manner and stops itself when the processing is done.
But if you want to perform simultaneous request at once, extend from Service. You will have create a worker thread to run this service as it doesn't create a separate thread.
Check developer guide for more info:
https://developer.android.com/guide/components/services.html
To communicate between two services, you have to make use of Broadcast Receiver to receive intents which you can send from your first service or use listener callback, but i would suggest you to use Broadcast Receiver and intents.
I have an IntentService that downloads data from a server and I would like the IntentService to check for server updates at a certain interval. The following posts however advice against repeating a Service using a Timer - and instead emphasize on using an AlarmManager:
Why doesn't my Service work in Android? (I just want to log something ever 5 seconds)
Android - Service: Repeats only once
Android service stops
From Android's reference manual, an IntentService is described as:
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
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.
The part I don't really understand is why an IntentService (the posts have questions that are directed towards a Service and not an IntentService) is not allowed to execute repetitively using a Timer as it creates its own worker thread for execution. Is it permissible to use a Timer within an IntentService ? Or are AlarmManagers the only solution to periodically execute an IntentService ?
An explanation to this would be most appreciated .
Or are AlarmManagers the only solution to periodically execute an IntentService ?
If you want it to work reliably, yes. Using AlarmManager is also much more friendly to the user.
First, do not have a Service of any form running except when it is actively delivering value to the user. Watching the clock tick is not actively delivering value to the user. Having a Service running gives your process a bit higher priority than other processes, in terms of what processes get terminated to free up system RAM for future work. Having a Service around unnecessarily -- such as simply watching the clock tick -- hampers the user's ability to multitask well, as you tie up system RAM unnecessarily.
This behavior will cause some users to attack you with task killers, such as swiping your app off the recent-tasks list. This will terminate your process, and therefore your Timer goes away too. Similarly, because too many sloppy developers keep their Service around for a long time, Android will automatically terminate such processes after some time, Service notwithstanding.
Finally, usually one facet of "check for server updates at a certain interval" is that you want this work to occur even if the device goes into sleep mode. With your everlasting-service approach, that will require you to keep the CPU on all the time, using a WakeLock. This will significantly impact the user's battery, causing your app to appear on the Settings app's "battery blame screen". That, in combination with the tying-up-system-RAM "feature", will likely incite some poor ratings for your app.
Instead, by using AlarmManager:
Your IntentService only needs to be running while it is doing its work ("check the server updates"), going away in between these events, so your process can be terminated to free up system RAM for other things that the user is doing
By use of the WakefulBroadcastReceiver or WakefulIntentService patterns, you can wake up the device briefly to do this work, then let the device go back to sleep again, thereby minimizing the impact on the battery
I had read quite a number of resources regarding the Service and IntentService. However when come to make a decision, I am not confident enough to choose which type to use in order to create a background service that will poll data from database in a time interval and stop it when I get the data I want since the data represent a status of a request, eg. ordering medicine confirmation status(pending, completed, in progress). I need to detect when a status is set to "completed" and send a notification to alert the user that the order is completed. After that the service will stop itself automatically.
Please kindly advice. Thank you.
Intent Service -
Works in Worker Thread , not in Main Thread.
Intended to execute their action is separate thread and then get shut down.
They do perform their operation and stops.
Ideal to perfrom things like htp get ,don't require to stay connected with server.
Service -
Runs in main thread.
Ideal when there is requirement to stay connected with server
(i.e. permanent tcp connection), the way you can go is to have a service (not an intent one) that performs the networking stuff using an asynctask or a more classic thread hosted in the service
It makes no difference. Use whatever you find easier. This question isn't worth spending any time worrying about. Just make sure you understand what code needs to run on the main (UI) thread and what code needs to run on a background (worker) thread. In IntentService the "long-running operation" needs to run in onHandleIntent() If you are using Service in onStartCommand() you would start your own background thread and execute the "long-running operation" on that.
I currently have a listview that is populated upon creation from a web server. I want it to either poll the database for updates routinely, or to allow a php script to update it. I would prefer that it be updated by the database, rather than polling.
As far as polling goes I know that I can implement a service or an asyncthread. I also have found the timertask class.
For AsyncThread: Can I have this be recurring continuosly? Would I call the .start method from the
For TimerTask: Is this less efficient than an asyncthread or service?
Also do I need to create the TimerTask inside of a thread? or will it create its own threads?
Trying to turn a server into a client, and a client into a server, is like trying to eat through the wrong orifice. It's fighting against the nature of the original design.
For one thing, you can't rely on your application to be on continuously, not on a phone anyway. Applications on cell phones have low priority. Applications on cell phones have limited energy they can use. Applications on cell phones are also not always going to be connected to the internet.
So for one thing, you'll want to use a Service on its own thread (you can use AsyncTask if you like). Your service will need its own thread so it doesn't block the UI thread waiting for responses. And you'll want to use AlarmManager to wake up or terminate your Service as needed (since your Service is bound to get killed a few times, through no fault of its own).
I am confused about where Android services run. I know services marked 'remote' run in their own processes, but what about ordinary local services?
The reason I ask is I want two local services to cooperate but not be blocked by each other. So for example, Service1 manages a network connection and receives packets. On receipt of a packet, I need that service to hand-off the packet to Service2 that processes the information and takes some action, including possibly sending a return message. I need the receipt, hand-off and processing to happen asynchronously, so the network service can continue to receive packets whilst the application service processes them. How do I ensure this happens?
I know one solution is to broadcast Intents, but how do I include custom data objects (i.e. packets) in an Intent? I don't want to implement the parcelable interface (overkill for local services) but I really need to be able to hand-off complex data objects between the services.
Thanks
Everything in your manifest file that is defined to run in the same process also share the same main thread. This thread is also sometimes the UI thread if that process has activities running in it. So, if you have two local services and they are running in the same process they are going to share the same main executing thread. In order for them to both do work 'at the same time' (until multicore android devices exist all execution is sequential anyway) then your service handling the network connection is going to need to do that in a separate thread. Your other service will need another thread as well.
Your problem is commonly called the producer-consumer pattern. Here's a link quick example of an simple implementation using blocking queues.