androidandroid-serviceandroid-service-bindingandroid-binder

Android communicating from Service to Clients


I'd like to keep a reference to each client that binds to a started & bound Android service. My service is NOT in a separate process.

I can have multiple clients bound, e.g. - 1 Activity and 2 Fragments. They may all be interested in a combination of different events returning from the Service. Ideally, I'd like to register each client with the Service when they bind and then iterate over each connected client and send them each the message.

Right now I am using the Binder to expose the Service's API to the client, but I am not happy using Broadcasts to send the data from the Service back to the clients. It feels so "loose". Wondering if there was a more concise & structured way of doing so ?

Message Handler is one way, but I feel like I will lose the binder API the clients are currently accessing the service API through.


Solution

  • The Bound Service approach detailed here is appropriate. You don't have to worry about Handlers, or even Intents (once the client is bound).

    Referring to the example at the given link: You can simply add functionality on to the LocalService object, e.g.,

    /** method for clients */
    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
    
    private Set<MyEventListener> mListeners = new HashSet<>();
    
    /** A MyEventListener (your Activity, Fragment, etc.) calls this in its
     * onServiceConnected() method, on the reference it gets from getService(). */
    public void registerListener(MyEventListener listener)
    {
        mListeners.add(listener);
    }
    
    public void sendEvent()
    {
        for(MyEventListener listener : mListeners)
        {
             listener.onEvent();
        }
    }
    

    ...and so forth. All methods execute synchronously, on the UI thread. All objects (Services and clients (MyEventListener)) are guaranteed to have a lifetime at least as long as the ServiceConnection. Also, the ServiceConnection will not experience an onServiceDisconnected() call until you explicitly unbind, since you're using an in-process service.