My name is Philipp C. Heckel and I write about nerdy things.

Android Example: Communication between Activity and Service using Messaging


  • Jun 10 / 2012
  • 22
Uncategorized

Android Example: Communication between Activity and Service using Messaging


I recently wrote my first little app for my Android smartphone and I was surprised how easy it was. Being familiar with regular Java, learning the new Android APIs was very simple for the most part. However, there was one thing that wasn’t particularly straight forward: communicating between an Activity, i.e. the user interface, and a background Service started by the application. After many hours, I found some sample code on Stack Overflow which I used to create a very generic reusable solution to start, stop and communicate with your own Service implementation.

The code below provides an easy way to:

  • Implement your own Android background Service
  • Start and stop the service from an Activity, i.e. the UI
  • Send/receive messages by the Service
  • Send/receive messages by the Activity

Solution

Here are three simple steps how to use my code:

  • Download and import the two Java classes AbstractService and ServiceManager
  • Inherit from AbstractService to implement your own service.
  • Add a ServiceManager to your Activity.

You can now:

  • Control the service with ServiceManager.start() and .stop()
  • Send messages to the service via ServiceManager.send()
  • Receive messages from the service by passing a Handler in the ServiceManager constructor
  • Send messages from the service to all listeners using AbstractService.send()
  • Receive messages in the service via the onReceiveMessage() callback

Example

Here is a small excerpt that shows how to use the code, i.e. how to implement your service and control it from the activity. You can find a full example on Launchpad.

Step 1: Inherit from AbstractService: Override onStartService, onStopService and onReceiveMessage, and use send() to send messages to the activity.

Step 2: Use the service in an activity with a ServiceManager: Instantiate a service manager, control the service with .start()/.stop() and send messages to the service with .send(). Note: To unregister the activity from the service, you should call .unbind() in the onDestroy()-callback.

Full code example

Checkout on Launchpad:
https://code.launchpad.net/~binwiederhier/+junk/android-service-example

Browse code on Launchpad:
http://bazaar.launchpad.net/~binwiederhier/+junk/android-service-example/files

22 Comments

  1. Praveen kumar.S

    nice example… easy to understand the concept this is good one ! thank u…



  2. Richard Helferty

    Great Work,
    I am trying to incorporate into an upgrade I am doing to my app. For some reason, the onServiceConnected method is not being called, so I can not send messages to the service from the activity. Any Ideas


  3. Stefano Soresina

    Very useful example, but I can not receive the message nell’activty, any ideas about this problem?


  4. Stefano Soresina

    I’m sorry, there was an error of my code, now it work, fantastic !





  5. Hang Liu

    This is a very nice example.
    But I have one question that I can’t figure out for a while.
    When I’m trying to use service.send(msg) to send a message directly after I call the service.start(), the message will not be sent successfully. It seems the service will only be able to bind to the activity after “a while” after the start() is called.
    Any ideas? Thanks a lot.


  6. Philipp C. Heckel

    @Hang Liu: Interesting. I have not encountered that behavior — but then again I have not been using the classes extensively.

    What’s odd about this is that ServiceManager.start() calls Context.bindService() which does synchronously bind and return. So there should not be such a behavior.

    Please let me know if you find the reason!


  7. Chris Doherty

    Hi Phililpp, this is my first attempt at services so bare with me. I want the service to run in the background while my app switches activities. It’s a downloader downloading 100’s of images. An action by the user in one of the other activities may mean an image will have it’s download priority promoted to #1 – to be attended to soonest. Even though the service is started in my main activity, I want the other activity to be able to communicate with this service. I am wondering, to do this, do I attempt to start another instance of the service, which will effectively connect the Activity2 to the existing service instance and send it my messages? Or is there some way of passing a reference to a service between Activiities? I guess I am being clear as mud here!
    Thanks for your code and any tips you can provide
    Chris


  8. syam

    Hi,
    example is good but i am searching for only background service it’s run when device start and updating the location information to local database or web service without UI , i searched many sites from google but no solution could u pl help


  9. Philipp C. Heckel

    The service will be running even if the Activity/UI is not running. That is the whole point of the service. Starting a service in the background is a different story and not part of this example.


  10. Chandra Shekar Daadi

    can this service be a singleton and be called from multiple activities??


  11. John

    Hi – thanks for the example code – I like it.
    One thing – I think I had a similar problem to Hang Liu above, where – as in your example code in this post, I tried to send a message immediately after starting the service in onCreate, but it didn’t work.
    I’m not sure, but I suspect the answer might be in this post: http://stackoverflow.com/questions/3055599/android-how-do-i-wait-until-a-service-is-actually-connected

    The salient point seems to be that the bind probably won’t even START until the activity’s onCreate is finished – and instead the early message should be put in the ServiceConnection object’s onServiceConnected method. The only problem with this, is that that code is inside your library code at present… in ServiceManager.java… if I’m not mistaken.

    Anyway – thanks for your help and ideas.


  12. Albert

    Thank you for sharing.
    I have one question.
    I don’t know that the 1 value isn’t displayed in this view. Start from 2?





  13. Bart

    Nice example. This made it a lot easier to understand.

    Thanks


  14. MQ

    Hi, thank you very much, this is a great set of classes.

    @John and @Hang Lui:
    I ran into the same issue, the service will not accept any messages until the connection is established (onServiceConnected()) is called. I fixed this issue in my case by adding a queue for messages that get sent once onServiceConnected() is called:

    public void send(Message msg) throws RemoteException {
    if(mIsBound)
    {
    if(mService != null && mIsConnected == true)
    {
    mService.send(msg);
    }
    else
    {
    // If the service is not ready, queue the messages until the connection is properly established.
    mMessages.add(msg);
    }
    }
    }

    Then inside onServiceConnected():
    Message msg = Message.obtain(null, AbstractService.MSG_REGISTER_CLIENT);
    msg.replyTo = mMessenger;
    mService.send(msg);
    mIsConnected = true;

    // If there are messages waiting, send them out.
    for(Message m : mMessages)
    {
    mService.send(m);
    }
    mMessages.clear();

    Hope that helps.

    Anyone figured out yet how to connect a new activity (one that did not start the service) to the service with this interface?


  15. Андрусик Ігор

    Hello. Please say me How to bind two Android Activites to one Service?