Can any Android experts explain when you would use
Context.bindService vs Context.startService to start a Service?
From the docs for Bound Services
A bound service is the server in a client-server interface. A bound service allows components (such as activities) to bind to the service, send requests, receive responses, and even perform interprocess communication (IPC).
In other words binding to a Service allows two-way interaction by exposing methods in the Service which are available through the IBinder via a ServiceConnection.
In contrast, using startService(...) performs more of a one-shot operation. This is only really useful if the Service can work in an autonomous fashion, i.e., it knows what it needs to do and doesn't need to be controlled further other than via any action and or data passed in the Intent used to start it. In general a Service which is started with startService(...) will not communicate directly with the component that started it (such as an Activity). It can however send data or results of an operation using a broadcast or by creating a Notification.
Related
I am curious to know why would you use Bound Service for 2 way interaction between Activity and Service when you can do the same kind of interaction with Started Service using local broadcasts and receivers defined in both Activity and Service
It will be helpful to know the pros and cons of each implementation.
I couldn't find any clear answer to this anywhere.
Using a bound Service is much more flexible. You can define methods on the Service (using AIDL) that return immediate results (synchronously), which you cannot do using LocalBroadcastManager. Using LocalBroadcastManager requires that you use your Service in a completely asynchronous way. This decouples the initiation of a service action with the return of the results (callback) which can make your code more complicated and more difficult to understand. Asynchronous use has some benefits, and there are places where you should use it, but if you have a bound Service you can choose exactly when to use synchronous calls and when to use asynchronous callbacks.
Also, the use of AIDL allows you to exactly describe the signatures of the services's method calls. If you use startService(Intent), you cannot guarantee that the caller will provide the correct arguments in the passed Intent, so you need to rely on the caller to "do the right thing" and/or you need to add a lot of additional argument verification.
Don't forget the comment from #CommonsWare about how LocalBroadcastManager only works if the Service is running in the same OS process as the rest of your app (which makes it unsuitable for programming things like system services, which are not running in your OS process).
A service is a component that runs in the background. It works to perform long-running operations without needing to interact with the user For example, a service might retrieve data over the network without stopping or blocking user interaction with an activity of an app or user may play music in the background while the user is in a different application. A service can be of two types or states:
Started: Once started, a service can run in the background indefinitely, even if the component which is started, is destroyed. A service is started when an app module or component, such as an activity, starts it by calling startService(). For example, retrieving contacts from phone book using service when Splash Screen starts.
Bound: A bound service offers a client-server interface that allows components to interact with the service, get results, send requests and even do so across processes with interprocess communication (IPC). A bound service is bound, when an app component binds to it by calling bindService().
I have found that it is possible to communicate with services by use of either Intents or direct binding . Why should direct binding could be useful ? and isn't it a bad practice that sounds like high coupling with components ?
Usually a service which is started with context.StartService() with intents performs a single operation and does not return a result to the caller.and this service can run indefinitely and the service should stop itself by calling stopSelf().
Where as bounded service offers a client server interface that allows components to interact with the service and send requests,get results and even do so across processes with inter process communication(IPC).One or more component can bound to this service.this service run only till at least a component is binded to it else it is destroyed(stopd).
want to know more on bounded and unbounded services. Please refer the below link
Bounded and unbounded services
What are the ways to communicate between an Activity and a Service on android?
Today I learnt how to communicate by sending an Intent from Activity and replying back using BroadcastRecevier.
Which are my other options? Does anyone have a tutorial/reference regarding this?
Answer to this question is:
There are several way for an activity to communicate with an service and vice versa. This section dicusses the different ways and gives recommendation which to use.
5.1. Activity binding to local service
If the Service is started in the same process as the Activity, the Activity can directly bind to the service. This is a relatively simple and efficient way to communication.
5.2. Using receiver
You can also use dynamically registered receivers for the communication. For example your activity can dynamically register a receiver and the service sends outs corresponding events.
5.3. AIDL for services in a different process
To bind to a service which runs in a different process you need to use Inter Process Communication (IPC) as the data needs to be send between different processes. For this you need to create a AIDL file which looks similar to an Java interface but ends with the .aidl file extension and is only allowed to extend other AIDL files.
This approach is required if your service should be provided to other applications, otherwise you should prefer a local service.
5.4. Sending Intent data and bundle to the services
The service receives data from the starting Android component and can use this data.
5.5. Handler and Messenger
If the service should be communicating back to the activity it can receive an object of type Messenger via the Intent data it receives from the Activity. If the Messenger is bound to a Handler in the activity the service can send objects of type Message to the activity.
A Messenger is parcelable, which means it can be passed to another process and you can use this object to send Messages to the Handler in the activity.
Messenger provides also the method getBinder() which allows to pass a Messenger to the activity. The Activity can therefore send Messages to the service.
Thanks to http://www.vogella.com/articles/AndroidServices/article.html
Ways to connect Activity to service:
Broadcasts: easiest way, implement a BroadcastReciever in each to listen to actions of others.
Messengers: Very good for multiple types of clients, Both service and client have a Messenger , service provides it Messenger in onBind(), clients sends a register/unregister message with its own messenger in replyTo() of message. Service saves client messenger. Now both can send/recieve messages.
IBinder: If you need full fledged remote IPC . Define an Interface for service with AIDL and pass Implementations to clients in onBind().
Android online reference has explanations of each.
The guys are right, you should really google for answers!
However, I recently learned a neat way to send intents to a service. You can simply call startService(myIntent) to send an intent to your service. If the service is not running, it will be started. If the service is running, you have the possibility to react on the new information.
I'm creating an application that connects to an XMPP server on Android. I want to keep the connection on till the user logs out.
Should I use a regular Service or a Bound Service to keep the connection on?
Any tips, advice and helpful information are welcomed.
I like this explanation:
Started services are easy to program for simple one way interactions
from an activity to a service, however, they require more complex and
ad hoc programming for extended two-way conversations with their
clients.
In contrast, bound services may be a better choice for more
complex two-way interactions between activities and services. For
example, they support two-way conversations.
So, as you said, If you want to interact with the service use bound service. With started services (or intent services) you could do it, only it would require more complex programming.
(by Douglas Schmidt: https://www.youtube.com/watch?v=cRFw7xaZ_Mg (11'10'')):
Here is a summary that helped me understand (thanks Doug):
Finally, one last link that helped me also:
http://www.techotopia.com/index.php/An_Overview_of_Android_Started_and_Bound_Services
Started services are launched by other application components (such as an activity or even a broadcast receiver) and potentially run indefinitely in the background until the service is stopped, or is destroyed by the Android runtime system in order to free up resources. A service will continue to run if the application that started it is no longer in the foreground, and even in the event that the component that originally started the service is destroyed
A bound service is similar to a started service with the exception that a started service does not generally return results or permit interaction with the component that launched it. A bound service, on the other hand, allows the launching component to interact with, and receive results from, the service.
A bound service is the server in a client-server interface. A bound service allows components (such as activities) to bind to the service, send requests, receive responses, and even perform interprocess communication (IPC). A bound service typically lives only while it serves another application component and does not run in the background indefinitely.
If all the code exists in one activity from user connected to user logout then go for bound service
But if it is code exists in multiple activities try with service
I found out the difference between the two and when to use it. If you want to interact with the service (for example send arguments etc), use bound service and it return the service object in the onServiceConnected method (where you can call methods in the service). You cannot interact with a regular service (from another class)
I want to do Bluetooth connection in Service. And there needs to be interaction between Activities and Services. The service should be started as soon as the app is started and should be able to communicate with UI Activities on certain situations.
What should be the appropriate way of doing it? If I bind the service from only one Activity then that service will be communicating only with that Activity. So, do I need to take AIDL based approach or is there any other way out for this?
Otherwise, can I have a class that extends Application class and then start the service from there and bind the Application class instead?
This is quite a broad question, so I'll answer as best as I can. From what I know of services, multiple activities can bind a single service, all having access to it. Only once all activities that bound the service end their connections (by unbinding), does the service actually stop.
The android documentation on services tells us:
... the system will keep the service running as long as either it is started or there are one or more connections to it with the Context.BIND_AUTO_CREATE flag. Once neither of these situations hold, the service's onDestroy() method is called and the service is effectively terminated
So my recommendation would be to bind the service from all activities that need to communicate with it. When binding with a service an IBinder is returned, which you can use to communicate with the service. Again according to the Android documentation on services:
Usually the IBinder returned is for a complex interface that has been written in aidl.
Although if you only need to perform simple communication with the service, you could use the Messenger class instead of writing full AIDL files. A sample of this can be found here.
Hope this answers your question!
You could bind directly to the Service as the above answer states, however there is no need for Messengers. Your service will be running in the same process as your activity 99.9% of the time. Messengers are designed for inter-process communication (IPC). Also no need for AIDL - that was designed for advanced IPC.
Instead, you should use: BroadcastReceivers and Intents. This is what they were designed for (communication between components in an app).