Perihan Mirkelam
Perihan Mirkelam

Reputation: 606

How to send data to an IPC client from a remote service in different processes

There are an IPC client and an IPC server(remote service) belonging to different processes. I need to start to send data continuously to the client after it binds to the remote service. I can bind to the service and call AIDL methods from the client, but I can't find a way to send data from the remote service to the client.

Upvotes: 4

Views: 933

Answers (1)

coderms
coderms

Reputation: 96

This is possible by the use of remote call backs in AIDL. Server implements an AIDL which allows client to register a remote callback (call back is also an AIDL) after binding to service. Then server can invoke the remote call back to send data to client when required. See below code snippets from Android API demos for the same.

IRemoteService.aidl

interface IRemoteService {
/**
 * Often you want to allow a service to call back to its clients.
 * This shows how to do so, by registering a callback interface with
 * the service.
 */
void registerCallback(IRemoteServiceCallback cb);

/**
 * Remove a previously registered callback interface.
 */
void unregisterCallback(IRemoteServiceCallback cb);

}

IRemoteServiceCallback.aidl

oneway interface IRemoteServiceCallback {
/**
 * Called when the service has a new value for you.
 */
void valueChanged(int value);

}

Both client and server side code can be seen at RemoteService.java

Client side code to register remotecallback

        private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the service object we can use to
            // interact with the service.  We are communicating with our
            // service through an IDL interface, so get a client-side
            // representation of that from the raw service object.
            mService = IRemoteService.Stub.asInterface(service);
            mKillButton.setEnabled(true);
            mCallbackText.setText("Attached.");

            // We want to monitor the service for as long as we are
            // connected to it.
            try {
                mService.registerCallback(mCallback);
            } catch (RemoteException e) {
                // In this case the service has crashed before we could even
                // do anything with it; we can count on soon being
                // disconnected (and then reconnected if it can be restarted)
                // so there is no need to do anything here.
            }

Server side code which calls the client remote callback

               `// Broadcast to all clients the new value.
                final int N = mCallbacks.beginBroadcast();
                for (int i=0; i<N; i++) {
                    try {
                        mCallbacks.getBroadcastItem(i).valueChanged(value);
                    } catch (RemoteException e) {
                        // The RemoteCallbackList will take care of removing
                        // the dead object for us.
                    }
                }
                mCallbacks.finishBroadcast();`
                

Upvotes: 2

Related Questions