3

How should a service communicate with an activity in real-time?

BroadcastReceivers seem too slow and unreliable. Sometimes they appear too slow or stop working entirely. As an example, there was a delay of a few minutes between sending and receiving broadcasts with one of my test applications.

I can't get traditional callbacks to work reliably. I am pretty sure you're not supposed to.

There's an option to bind a service. Is that suitable for real-time communication?

I intend to send small integer updates roughly 20 (edited) times a second.

Am I looking in the right direction?

To narrow the scope of this question:

My application is an audio MediaPlayer. I need the service to host the MediaPlayer. I would like the MediaPlayer service to send updates to my GUI which mainly consist of the current position of the audio being played.

My question is - are bound services suitable for this task? If not, what alternatives are there?

  • Thanks for the downvotes. I assume that is because this question is not appropriate? Would this be better on Overflow? Sorry for the trouble. – David Dec 28 '15 at 12:26
  • Looking at the other questions here, I think this is the right place to ask. Could anyone clarify the downvotes? I'm sure there's a perfectly good reason for them. – David Dec 28 '15 at 13:12
  • 2
    Note the downvoter, but your question is quite broad. – James McLeod Dec 28 '15 at 13:50
  • @James Thanks for your comment. I will think about rewriting this to add more detail. – David Dec 28 '15 at 15:55
  • It seems that callbacks work correctly with bound services. I'll post a full answer once I've got it all worked out. – David Jan 9 '16 at 3:12
2

In Android, a service is used to run some background task even when the user interface element which initiated that task is no more in foreground.

For example: In a social networking app where the user wants to upload a video to the server, the video should continue to get uploaded in background even when the application who requested the video to be uploaded is no more in foreground (e.g. the user receives a call in the meantime).

I am assuming in your case, you want the song to continue to play even when your user interface element (the music app) is not in foreground.

Therefore definitely service is the way to go.

In Android there are two types of services (http://developer.android.com/guide/components/services.html)

  • Started Service : Used for long running task where intermediate updates are not required. So for example if you want to upload a video in background and only intimate the user that the upload was a success or a failure, then you use a started service and use notifications to inform the user of the status (success or failure)
  • Bound Service : Used for long running task where there is a client/server relationship between the invoker (in this case the app) and the service.

In android you can create a service which is started and bound at the same time. My suggestion would be to create such a service. The started part of the service will play the song in the background and the bound part of the service will provide updates of the current position of the song being played.

In the meantime, if the app goes in background, then because the service is started the song will continue to play without providing updates of the current position of the song.

  • Thanks for the reply. I have callbacks working correctly with bound services. I'll mark this accepted once I've done a little more research. – David Jan 14 '16 at 13:16
  • Welcome. Please let me know if you need further information – Anay Tamhankar Jan 16 '16 at 10:57
3

You can also use Pending Intent,Event Bus or Messenger for real time communication from service with activity. Check out my blog post at below link which covers all these approaches with example-

https://androidlearnersite.wordpress.com/2018/02/23/communicating-from-services/

Pending Intent

Communication between service and Activity can be done using PendingIntent.For that we can use createPendingResult() which creates a new PendingIntent object which you can hand to service to use and to send result data back to your activity inside onActivityResult(int, int, Intent) callback.Since a PendingIntent is Parcelable , and can therefore be put into an Intent extra,your activity can pass this PendingIntent to the service.The service, in turn, can call send() method on the PendingIntent to notify the activity via onActivityResult of an event.

Event Bus

You can have the service raise events which activities or fragments can listen for and respond to using Event Bus.Event Bus can be integrated using this library which is explained here.

Messenger

Messenger references to a Handler, which others can use to send messages to it.Messenger is parcelable ,and can therefore be put into an Intent extra,so your activity can pass this Messenger to the service.Service will populate Message object with whatever data needs to be send.Whenever an event needs to be send to the activity,we need to call send() on Messenger supplying the Message object as parameter.The Handler inside activity will receive the message via handleMessage() , on the main application thread, and so can update the UI or perform necessary operation.

  • Thank you for the link, but please summarize the details in your answer here. Links get deleted; answers stay – David Apr 24 '18 at 14:20
  • 1
    @David updated my answer – Android Developer Apr 25 '18 at 5:03
  • An alternative to the "Broadcast Intents" at the bottom of the post, is to make your activity "singleTop", and then just send a startActivity call/intent (with FLAG_ACTIVITY_NEW_TASK flag). This has the advantage of working even when the activity is destroyed, or suspended due to the screen being off. (see: stackoverflow.com/a/41657247/2441655) – Venryx Jul 29 '19 at 22:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.