Question

I am trying to implement AIDL and I just do not understand how it works. By this I mean what is the progression of calls to methods?

I dont understand how to get an object from the service to my activity through AIDL. I have been using google docs for guidance but I am confused.Thanks

UPDATE:

In Service Connection I have these lines where mCallback is a IRemoteServiceCallback.

 public void onServiceConnected(ComponentName name, IBinder service) {
            mRemoteInterface = IRemoteInterface.Stub.asInterface(service);
            Log.v(TAG, "Interface bound.");
            try{
                mRemoteInterface.registerCallback(mCallback);
            }catch(RemoteException e){

            }
            Toast.makeText(MainActivity.this, "Remote Service Connected",
                    Toast.LENGTH_SHORT).show();
        }

Here is registerCallback, where mCallbacks is a

final RemoteCallbackList <IRemoteServiceCallback> mCallbacks

    = new RemoteCallbackList <IRemoteServiceCallback> ();

.....

public void registerCallback(IRemoteServiceCallback callback)
                throws RemoteException {
            if(callback != null){
                mCallbacks.register(callback);
            }

        }

The only method that IRemoteServiceCallback(mCallback) has is:

public void valueChanged(int value) {
        mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
    }

I also have a Handler but I am not quite sure what to do with that:

 private Handler mHandler = new Handler() {
    @Override public void handleMessage(Message msg) {
        switch (msg.what) {
            case BUMP_MSG:
                Log.d(TAG, "Received from service: " + msg.arg1);
                break;
            default:
                super.handleMessage(msg);
        }
    }

};

UPDATE 2:

AIDL Steps -from what I understand-.

  1. I call bindService(service,connection,flags) from MainActivity

  2. onServiceConnected is automatically called after I call bindService and a connection is established. Inside there, I get the IBinder and then call registerCallback which puts a IRemoteServiceCallback[WHERE DOES THIS CALLBACK COME FROM??] into RemoteCallbackList for later access

Now, I noticed that there are TWO mHandlers, one in the service and one in the activity. [WHEN ARE THESE CALLED and WHAT IS THE DIFFERENCE BETWEEN THEM IN TERMS OF USAGE]

Now, RemoteCallbackList has the callbacks that I need and I can see that in the mHandler of the activity class I am able to finally get the objects that I want.

Was it helpful?

Solution

Cross-application services in Android are based on Binder, a kernel-level IPC system (this is where the IBinder class name comes from). When you bind to a remote service (that is, one outside of your application), it can return an object to you. However, since you don't know what the actual type is (methods, fields, etc), you can't cast it to a usable type.

This is where AIDL comes in - it is a language-agnostic way of specifying interfaces - collections of methods and their parameters (it also looks deceptively like Java - it's not). If both the client and the server use the same .aidl file, you can bind to the object via the generated Java interfaces - IRemoteService.Stub.asInterface(obj). On the service side you just have to implement that same interface in some language (some of the services in the framework are in C++) and the IPC mechanism will take care of the rest.

That said, you don't need to use AIDL unless you export your service and want external applications to be able to use it. If not, just implement IBinder in your application and cast the object received in onServiceConnected directly, since you know its type.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top