Search code examples
javaandroidserviceremote-accessremoteobject

A thread calling Remote service waits for method to finish?


I have made a simple test of calling a remote service (on a different process) and I found something very suprising.

Suppose we have two processes: Process-A with Thread-A and Process-B.

If process A is runnign Thread-A and Thread-A calls a remote void method using IPC - AIDL. What will happen is: Process-B will have one of its Binder Threads run the method called. During this time Thread-A in Process-A will wait. Only after the Binder thread in Process-B will finish the method call, Thread A will be notified and resume its work.

My question: Is this a standard behavior? And if so, why is it like that? Thread-A should not wait if its a void method. (is "oneway" related to it?)

My code:

In Process A:

Log.d("Text", "Lior: Client: Thread: " + Thread.currentThread().getName() + " Passing parcelableClass:     parcelableClass.hashCode: " + parcelableClass.hashCode());
for(int i = 0; i < 1; i++) {

_iRemoteServiceBinder.passObject(parcelableClass);

}
Log.d("Text", "Lior: Client: Thread: " + Thread.currentThread().getName() + " Passed parcelableClass:     parcelableClass.hashCode: " + parcelableClass.hashCode());

In Process B:

private final IRemoteServicePassObject.Stub _binder = new IRemoteServicePassObject.Stub() {

    @Override
    public void passObject(ParcelableClass parcelableClass)
            throws RemoteException {

        Log.d("Text", "Lior: Service: got pacelableClass: a: " + parcelableClass.getA() + 
                " b: " + parcelableClass.getB() + 
                " s: " + parcelableClass.getS() + " hashCode: " + parcelableClass.hashCode()
                + " Running thread: " + Thread.currentThread().getName());

        try {

            Thread.currentThread().sleep(5000);

        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        Log.d("Text", "Lior: Service: Finished: "
                + " Running thread: " + Thread.currentThread().getName());

The result I am getting:

01-15 19:52:03.292: D/Text(22792): Lior: Client: Thread: main Passing parcelableClass: parcelableClass.hashCode: 1096225792 01-15 19:52:03.297: D/Text(23014): Lior: Service: got pacelableClass: a: 1 b: 2 s: String hashCode: 1096136272 Running thread: Binder Thread #2 01-15 19:52:08.302: D/Text(23014): Lior: Service: Finished: Running thread: Binder Thread #2 01-15 19:52:08.312: D/Text(23014): Lior: Service: running new thread: LiorThread 01-15 19:52:10.342: D/Text(22792): Lior: Client: Thread: main Passed parcelableClass: parcelableClass.hashCode: 1096225792


Solution

  • Found the answer.

    Any thread calling Remote method is waiting until the method is finished in the remote process. In order to make the call asynchronous - we need to define the AIDL as oneway. for example: oneway interface IRemoteServiceOnewayAIDL {