Reputation: 12455
I have two apps: One is called my-app.apk, the other my-service.apk. The service app just defines a single Android Service, which can be bound by the primary app to execute some methods. This is done using Androids AIDL interface, and it works great - so far.
Now I want to change the interface of the service, and I am wondering what I have to watch out for. I changed the file IRemote.aidl of my-service.apk to the following:
package com.example.myservice;
interface IRemote {
void printHello();
void print(int i);
}
And just out of curiosity I changed the IRemote.aidl of my-app.apk to the following (note the differences!):
package com.example.myservice;
interface IRemote {
void printHello();
void printYeahThisHasADifferentNameAndParam(String s);
}
Now I got a completely unexpected result: The call to
printYeahThisHasADifferentNameAndParam("hello world");
from my application resulted in the log output "11". Why??
So here are my questions:
Thank you in advance for your help! :-)
Cheers, Marc
Upvotes: 1
Views: 4054
Reputation: 1484
If you take a look at the code generated by the AIDL compiler, you will see that RPC via Binder calls methods by sequential number. Every method in the interface gets number assigned, like:
SIZE = ::android::IBinder::FIRST_CALL_TRANSACTION + 0,
SETSIZE = ::android::IBinder::FIRST_CALL_TRANSACTION + 1,
READ = ::android::IBinder::FIRST_CALL_TRANSACTION + 2,
WRITE = ::android::IBinder::FIRST_CALL_TRANSACTION + 3,
SYNC = ::android::IBinder::FIRST_CALL_TRANSACTION + 4,
This number is then used by the calling side to map called method to flat Parcel buffer and by receiving side of IPC to select the generated method to unmarshall the serialized parameters data and finally call the real implementation.
Thus if you replace the method number 1
definition on the calling side, but still have old implementation on the receiving side, you will call the old implementation with completely bogus data. There is no type information in the serialized Parcel data of method arguments (besides the method number itself), so it will happily deserialize new method call parameters buffer as old ones and try to call implementation.
Upvotes: 4