Search code examples
androidoutaidl

Difficulty using only out parameters in .aidl file


I am trying to get my Android service to be able to just send changes back to the Activity, so I am trying to just use out parameters, as there is nothing coming in from the Activity, once the service is started.

Here is my .aidl file:

oneway interface IMyServiceCallback {
    void dataChanged(out double[] info);
    void pathChanged(out List<ParcelableInfo> info);
}

I am stuck on how to pass data from the service so it will be sent over to the Activity.

So this is in my Service, but there is nothing in mCallback that will allow me to pass in the parameters that will then be sent back to the Activity.

private final IMyServiceCallback.Stub mCallback = new IMyServiceCallback.Stub() {

    @Override
    public void dataChanged(double[] info) throws RemoteException {
    }

    @Override
    public void pathChanged(List<ParcelableInfo> info) throws RemoteException {
    }

};

So, I am not certain how to call mCallback.dataChanged() where it will pass back new double[] { 1.0, 1.1};.

On the Activity side what I am trying to do is, as I am assuming that the parameter passed in is the data I want from the Service.

private IMyServiceCallback mCallback = new IMyServiceCallback.Stub() {
    @Override
    public void dataChanged(double[] info) throws RemoteException {
        mHandler.sendMessage(mHandler.obtainMessage(DATA_MSG, info));
    }

    @Override
    public void pathChanged(
            List<Parcelable> info)
            throws RemoteException {
        mHandler.sendMessage(mHandler.obtainMessage(PATH_MSG, info));
    }
};

I am using the oneway keyword also since all the communication flows from the Service to the Activity.


Solution

  • Your service should broadcast through all remote callbacks registered in binder:

    private final RemoteCallbackList<IMyServiceCallback> remoteCallbacks = new RemoteCallbackList<IMyServiceCallback>();
    
    private void sendNewData(final double[] info)
    {
      final int n = remoteCallbacks.beginBroadcast();
      for (int i=0; i<n; i++)
      {
        final IMyServiceCallback callback = remoteCallbacks.getBroadcastItem(i);
        try
        {
          callback.dataChanged(info);
        } 
        catch (RemoteException e)
        {
          Log.e(TAG, "Broadcast error", e);
        }
      }
      remoteCallbacks.finishBroadcast();
    }
    

    You can find complete example in API demos.