Send message from Activity to Service and vice versa - android

I have never worked with services before, but I looked at many posts and tutorials and I never quite understood how this works.
So what I need is something (like a Service) that runs in the background independently of the apps lifecycle to receive and execute requests asynchronically.
In more detail I want this to be a download queue.
I planned on doing this by having a service started if the user requests a download. If another download is requested while the first isn't finished the service puts it into its queue. The service sends periodical messages so the UI gets updated. The user can also pause or cancel a download (so the activity has to have the ability to send messages to the service).
I know how to do the download stuff and I think I know how to start the Service, but I don't understand how to send messages to the service.
For messages to the Activity I would do something like this:
private void sendUpdateMessage(Bundle data) {
Intent intent = new Intent("DownloadUpdate");
intent.putExtra("data", data);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
For messages to the Service I guess there has to be some sort of binding (which I don't understand well). I found this Communication between Activity and Service or this https://developer.android.com/reference/android/app/Service.html#remote-messenger-service-sample, but this seems very complicated and I sadly do not understand it.
It would be nice if anyone had a simple explenation for how to communicate between Activity and Service.
(Again, I know there are post on this topic on Stackoverflow, but for some reason I do not understand how to do it properly)

I found a very helpful page with great examples:
Effective communication between Service and Activity
There are three possible ways:
Broadcasts and BroadcastReceivers
The simplest solution uses Broadcasts and BroadcastReceivers. However, this method has the following disadvantages:
The message sender does not know who will receive the data (it broadcasts the message).
Broadcasts consume a lot of bandwidth and are not suited for high traffic.
Binder
For Activities and Services used in one application the “Binder” solution is recommended. After binding with the service, the Binder will allow the activity (or other class bound to the service) to call any public method of the service.
Messenger
The recommended method of communication between Activities and Services for different applications’ Inter-Process Communication (IPC) is by using Messengers. In this case, the service defines a handler for different incoming messages. This handler is then used in Messenger for transferring data via messages.
To get bi-directional communication, the activity also has to register a Messenger and Handler. This Messenger is passed to the service in one of messages. Without this the service wouldn’t know to who it should respond.
For my project I chose the last one.

Related

BroadcastReceiver and ResultReceiver in android [duplicate]

What is difference between BroadcastReceiver and ResultReceiver in android?
Result Receiver:
Generic interface for receiving a callback result from someone.
Broadcast Receiver:
Base class for code that will receive intents sent by sendBroadcast().
EDIT:
Background: All networking operations/long running operations should take place away from the main thread. Two ways to do this :
Async task - For Simple networking like say retreive an image/ do db
processing
Service - For Complex long running background process
If you need to perform work outside your main thread, but only while the user is interacting with your application, then you should probably instead create a new thread and not a service. For example, if you want to play some music, but only while your activity is running, you might create an Async Thread. But if you want the process to continue even after the user exits the app (say a download) then use a service
Lets say you pick 2. Now
You activity sends a web request to your service
Your service executes that using say DefaultHttpClient
It sends back data to your activity.
The third step of receiving data here can be done in two ways
1.) Broadcast receiver: Multiple receivers can receive your data. Used if you want to send data/notifications across applications(say you are also interacting with fb and twitter, multiple receivers for your web broadcast),
whenever you send broadcast its sent system wide.
2.) Result receiver: Your application is the only receiver of the data. It is an Interface you implement and pass it to the intentService through putExtra. IntentService will then fetch this object
and call its receiver.send function to send anything (in bundle) to
calling activity. Result receiver has
preference over broadcast receivers if your all communication is
internal to your application
EDIT: I should also mention this caution
Caution: A service runs in the main thread of its hosting process—the
service does not create its own thread and does not run in a separate
process (unless you specify otherwise). This means that, if your
service is going to do any CPU intensive work or blocking operations
(such as MP3 playback or networking), you should create a new thread
within the service to do that work. By using a separate thread, you
will reduce the risk of Application Not Responding (ANR) errors and
the application's main thread can remain dedicated to user interaction
with your activities.
A BroadcastReceiver is a receiver receiving broadcasts. Those are sent by someone in the intention that there can be many receivers receiving them (like radio broadcasts).
A ResultReceiver on the other hand is intended to receive a callback result from someone. So this could be compared with a walkie talkie, where you call someone and then are going to receive an answer (a result) from the one you called.
These two classes are completely different. It's actually quite the same difference as between Broadcast and Result.
what it Broadcast? In simple words it's some message which is visible to whole system and it can be consumed by every part of the system (which knows the contract), it wasn't originated by smb reuest;
what is Result? It's something we're expecting to receive from another part of the system. Usually there's only one receiver for result and usually that receiver has requested processing to obtain result (feel the difference - for broadcast nobody needs to do any 'request' to let it originated);
That was explanation from logic point of view. From the code perspective if You would compare BroadcastReceiver and ResultReceiver You could observe huge difference. Basically both classes are built on top of IPC but BroadcastReceiver is much more complex because of it's different nature (which I've tried to explain in first part).
Broadcast Receiver
A broadcast receiver is a component that responds to system-wide broadcast announcements. example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work. For instance, it might initiate a service to perform some work based on the event.
Result Receiver
If your service is going to be part of you application then you are making it way more complex than it needs to be. Since you have a simple use case of getting some data from a Restful Web Service, you should look into ResultReceiver and IntentService.
This Service + ResultReceiver pattern works by starting or binding to the service with startService() when you want to do some action. You can specify the operation to perform and pass in your ResultReceiver (the activity) through the extras in the Intent.

Communication with a service from different applications

I have a few applications that connect to a network service in order to call a few messages. As the communication with this network service is planned to change, I was thinking to implement a service that will deal with the communication with the network service, and the applications will just send intents or messages to this service. My idea is to have this service standalone, started after boot up, so it needs to be started service. It will connect to the network service and will wait for commands from the applications. So far, I found that Messenger is nearest to what I need, but I think it can only work as a bound service.
Is there already something I can use for my case?
If not, then am I correct that I would need to:
implement a started service
use HandlerThread to handle the input messages - my preferred way is to use intents, but so far I don't know how to do it
So as pskink pointed out, the way to go is using Messenger.
I used com.example.android.apis.app.MessengerService (from Android SDK samples) as an example of such service.
The service is started on reception of ACTION_BOOT_COMPLETED and (on my device with Android 4.2) when the first client tries to bind to the service, the service's onCreate and onBind are called. The communication occurs by sending Message objects and I have defined an enum with the supported messages listed (so I am not using AIDL directly).

Communication between Service and Activity on Android

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.

Broadcast Receiver and ResultReceiver in android

What is difference between BroadcastReceiver and ResultReceiver in android?
Result Receiver:
Generic interface for receiving a callback result from someone.
Broadcast Receiver:
Base class for code that will receive intents sent by sendBroadcast().
EDIT:
Background: All networking operations/long running operations should take place away from the main thread. Two ways to do this :
Async task - For Simple networking like say retreive an image/ do db
processing
Service - For Complex long running background process
If you need to perform work outside your main thread, but only while the user is interacting with your application, then you should probably instead create a new thread and not a service. For example, if you want to play some music, but only while your activity is running, you might create an Async Thread. But if you want the process to continue even after the user exits the app (say a download) then use a service
Lets say you pick 2. Now
You activity sends a web request to your service
Your service executes that using say DefaultHttpClient
It sends back data to your activity.
The third step of receiving data here can be done in two ways
1.) Broadcast receiver: Multiple receivers can receive your data. Used if you want to send data/notifications across applications(say you are also interacting with fb and twitter, multiple receivers for your web broadcast),
whenever you send broadcast its sent system wide.
2.) Result receiver: Your application is the only receiver of the data. It is an Interface you implement and pass it to the intentService through putExtra. IntentService will then fetch this object
and call its receiver.send function to send anything (in bundle) to
calling activity. Result receiver has
preference over broadcast receivers if your all communication is
internal to your application
EDIT: I should also mention this caution
Caution: A service runs in the main thread of its hosting process—the
service does not create its own thread and does not run in a separate
process (unless you specify otherwise). This means that, if your
service is going to do any CPU intensive work or blocking operations
(such as MP3 playback or networking), you should create a new thread
within the service to do that work. By using a separate thread, you
will reduce the risk of Application Not Responding (ANR) errors and
the application's main thread can remain dedicated to user interaction
with your activities.
A BroadcastReceiver is a receiver receiving broadcasts. Those are sent by someone in the intention that there can be many receivers receiving them (like radio broadcasts).
A ResultReceiver on the other hand is intended to receive a callback result from someone. So this could be compared with a walkie talkie, where you call someone and then are going to receive an answer (a result) from the one you called.
These two classes are completely different. It's actually quite the same difference as between Broadcast and Result.
what it Broadcast? In simple words it's some message which is visible to whole system and it can be consumed by every part of the system (which knows the contract), it wasn't originated by smb reuest;
what is Result? It's something we're expecting to receive from another part of the system. Usually there's only one receiver for result and usually that receiver has requested processing to obtain result (feel the difference - for broadcast nobody needs to do any 'request' to let it originated);
That was explanation from logic point of view. From the code perspective if You would compare BroadcastReceiver and ResultReceiver You could observe huge difference. Basically both classes are built on top of IPC but BroadcastReceiver is much more complex because of it's different nature (which I've tried to explain in first part).
Broadcast Receiver
A broadcast receiver is a component that responds to system-wide broadcast announcements. example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work. For instance, it might initiate a service to perform some work based on the event.
Result Receiver
If your service is going to be part of you application then you are making it way more complex than it needs to be. Since you have a simple use case of getting some data from a Restful Web Service, you should look into ResultReceiver and IntentService.
This Service + ResultReceiver pattern works by starting or binding to the service with startService() when you want to do some action. You can specify the operation to perform and pass in your ResultReceiver (the activity) through the extras in the Intent.

Design approach to use in Android when several activities need to connect to a service

I have a class that starts a Bluetooth reading thread and another that receives/decodes what's read from that port and produces some output logs depending on the information read.
In my design, those 2 components form a service for my application (multiple activities) from where I would like to start/stop getting the output logs on a continuous basis (typical frequency of 2-3 logs per second).
My questions:
1) Should I derive from Service or IntentService. The doc says about IntentService: "This is the best option if you don't require that your service handle multiple requests simultaneously". This may be my case since the main activity will start/stop the service...
2) What would be the appropriate way to catch the service events? Does the BroadcastReceiver is appropriate for this type of communication?
3) I may need to occasionally send some stuff to the Bluetooth port. So, I'll have to pass information from my application to the service. Does the PendingIntent should be used for that?
Thank you!
Should I derive from Service or IntentService
IntentService is designed for discrete tasks, not stuff that would run indefinitely until the user manually stops it. I would use Service.
What would be the appropriate way to catch the service events? Does the BroadcastReceiver is appropriate for this type of communication?
That is certainly one approach. You might use the LocalBroadcastManager from the Android Support package to reduce overhead and keep everything private to your app. Have your activities register a receiver in onResume() and remove it in onPause(). The foreground activity will then be notified of events.
I may need to occasionally send some stuff to the Bluetooth port. So, I'll have to pass information from my application to the service. Does the PendingIntent should be used for that?
No, I would have the activity simply send a command to the service via startService(), with the data to be passed included in extras on the Intent. If you have data that cannot be packaged as extras, you may need to consider binding to the service, so you can get a richer API, though this makes configuration changes more annoying.

Categories

Resources