I've an application with several activities bounded with a service.
The service open, in an asynctask, a socket connection and start listening (while(true)) the incoming message from a socket server.
the question is: how to send a callback to the several activities that a message is arrived?
thanks in advance
Are you binding the activities to the service with onBind()? If so, why? onBind() usually isn't necessary.
As far as I can tell, you're listening for incoming messages from a server. Have you investigated using Google Cloud Messaging?
The activities don't have to be bound to the Service. It will remain running until something shuts it down. You can run an AsyncTask on it, but you might even want to use your own background HandlerThread.
In any event, to communicate back to the activities, use a LocalBroadcastReceiver and send broadcast Intents from the Service.
Related
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.
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).
I start a service from my main activity using startService(). The service checks for sockets on localhost. When it receives a socket, it reads data from it. I would like to hide the notification bar when it receives socket with specific data. I already coded a function hideNotificationBar() which is located in my main activity. The problem is I don't know how to call this function in main activity from service.
Thanks for any help!
Send a Broadcast from Service. Register your Activity to receive this broadcast and act upon it.
This approach solves the problem of storing/acquiring the reference to Activity, which might become inactive during the lifetime of your Service.
The downside is that you can only send simple types, Bundle or classes implementing Parcelable via a broadcast Intent.
I suggest you have a look at MessengerService and MessengerServiceActivities from API Demos application.
Basically, idea is to have Handler class inside both your activity and service that handles communication between the two. Use ServiceConnection in the activity to establish connection with the service.
My app uses the Android XML-RPC project to communicate with a server. After the connection is established the app needs to keep the connection alive by sending a message to the server every xx second. The app also contains multiple Activities that need to send and receive messages using the connection.
What's the proper way to implement this?
Using a IntentService and BroadcastReceiver?
Or just a Thread?
This looks like a perfect job for a Service started by the AlarmManager.
Your service in its onStart method will get whatever information you need for connection (like token, username, ...) from the preferences for instance. You can trigger the service start by using the AlarmManager sending on a regular basis an intent to start the service.
Another option would be to have a service started in the background, running a thread that does the communication each X seconds (use a sleep(delay) between calls.
My application contains a single main Activity and a service.
Service will run in background as long as possible even if main Activity is inactive, so I had to launch it with startService() instead of binding them together.
There would be many messages and data exchange between Activity and Service while running.
I'm planning to use broadIntent() to finish those communication, but you know, intents are all asynchronous. But sometimes synchronous communication is required.
How can I get them synchronously communicated with each other?
Thanks.
i suggest you to look for bindService and AIDL.This lets you open a communication channel between the activity and the service.
what about using LocalBroadcastManager, it will send broadcast from service to local activity only.
http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html