I coded an IntentService where I send a command line. Is related to an activity where I'm trying to program a Console. The activity's purpose is to do a 'command prompt' where I can send and receive to/from the server.
The Service's action is:
COnnect to the server
Send command line
Get response
Retrieve response to user
The main problem is that every time I send a command line, the Service has to reconnect to the server. (Cause every time I'm starting the whole Service)How can I avoid this step?
I would like to "keep alive" the service waiting for a command line to send, without the need of reconnect every time I execute its action.
Is there any way to do it action-responsive? I mean, I start the service and every time I set its action (setAction) and put the line I want (putExtra). Then I have to start the service again?
Good night. Tomorrow I'll be back :)
Thanks in advance!
Due to its "one shot" design, using an IntentService isn't a good approach IMO.
If you don't want to start the service each time you send a command, then I'd suggest you 'bind' to a standard Service (see Bound Services). If you bind to the Service in your Activity's onResume() method and unbind in onPause() your Activity will be able to directly call methods in the Service.
You will, of course, have to create your own worker Thread in your Service to handle any work involving your network connection however. If you want any tips on how to do that, look at the source code for IntentService - it's fairly straight-forward.
Don't use an IntentService. Per the documentation:
the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
Instead, you should consider using a normal Service (calling stopSelf()) when you want to stop the service (and your connection to the server). Or, if you'd like the connection to the server to have the same lifecycle as the activity, you can create a bound service: it will start when your activity binds to it and then stop when the last activity is unbound.
Related
I'm developing an app that communicates with an embedded device via BLE (Bluetooth Low Energy). The app allows the user to send commands via an activity. Meanwhile the app needs to send location data in the background. The location data must be sent constantly, even if the activity is closed and opened multiple times over the day.
I cannot separate the continues location updates from the command requests. Because all BLE transmissions must be synchronized by one queue to prevent simultaneous transmissions which would cause package loss.
After reading the official guide (https://developer.android.com/guide/components/services#Basics), my first idea was to use a foreground service because the service must not be terminated when the activity is closed. That works fine for sending the location data. However, for sending the commands I have to communicate with the service after it has been started. I read that it's not recommended to use both startService() and bindService() but instead to decide for one way. As far as I understood a bound service can be destroyed when the referencing context (the activity in my case) is destroyed. So I guess binding to the service is not an option for me.
Another approach to talk to a started service is to send commands using broadcasts and receiving them in the service (sending commands from Activity to Service in android).
But I think there must be a better solution that I miss. What came to my mind is simply calling startService() every time I want to send a Bluetooth command. I guess that would work. But is it good practice? Effectively, I would call startService() dozens of times during a typical use case before calling stopService().
Oh wow... I read through the whole guide but overlooked this sentence in the method documentation:
startService()
Every call to this method will result in a corresponding call to the target service's onStartCommand(Intent, int, int) method, with the intent given here. This provides a convenient way to submit jobs to a service without having to bind and call on to its interface.
https://developer.android.com/reference/android/content/Context#startService(android.content.Intent)
Hope it helps in case that someone stumbles across it..
You don't have to bind the service to anything. It's enough to start it and then make sure you call startForeground on it. That will keep your process running without being killed by the system. You don't have to place your BLE code in the service class but can have it wherever you want.
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.
There is some long processing that need to be completed, so I put it in a service. The activity must be able to connect to the service, show the user current results from the service. So I start the service with start Service and later call bind Service (with BIND_AUTO_CREATE) as in LocalService from http://developer.android.com/reference/android/app/Service.html#ServiceLifecycle. I want it to run until its job is done, and then self stop, even if client is still connected to it. (or determine the client to unbind) Is any way to do it with the sample LocalService?
I was considering passing a handler to the service so that it can send messages back to the activity, but I don't want the activity to get leaked. I am just getting used with services, so maybe I am misusing something.
EDIT: The workload consists of several threads, synchronized and run in parallel, so I guess is not a good candidate for intent service. Some data analysis is done in background service, and when the user restarts the activity that started the service, it should display some graphics according to current values computed by background service. All background processing is triggered at the beginning, and need only inspection later on, when activity connects to it. Android should not be able to stop the service. When the job is finished, the service should be able to terminate even if the activity is connected to it.
I just recorded a callback with the service. If the activity is not connected to service, it sets the callback to null. In this callback I call stopService() and then finish() on the activity. I am not sure that it is the best method, but it works fine for me.
If you want a service to be stopped when it is finished, I think what you are looking for is IntentService, they work as services, but run in another thread and when they are completed they dissappear.
Check this out
EDIT: NickT link is better, check that out! :)
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'm about to develop an application for Android.
I need to continuously run an update thread that executes a task in a given interval. And this thread needs to be shared between activities.
I would also like to notify the active Activity when the thread executes a task.
In iOS I would execute a thread from the AppDelegate and then send notifications, but how do I achieve this with the Android SDK?
I'd say create a Service that does the work for you. When it starts or finishes (or at any point you want), you can send a custom broadcast intent to indicate all parties that your service has passed this point. See Intents.
If you want to start this Service periodically, also have a look at the AlarmManager. That allows you send a broadcast intent periodically - in this case the intent that starts the service.
Also note that it's usually wiser to to terminate a service via stopSelf() when it's work is done. Run it again via intent when needed. Keeping it alive all the time isn't a good idea when it comes to battery life.
Make a service and implement a thread with infinite loop and from there you can do your job....to update data in activity you can make a static method and you can call it from there with appropriate arguments....