FileDocCategorySizeDatePackage
TimedRemoteCaller.javaAPI DocAndroid 5.1 API4366Thu Mar 12 22:22:10 GMT 2015android.util

TimedRemoteCaller

public abstract class TimedRemoteCaller extends Object
This is a helper class for making an async one way call and its async one way response response in a sync fashion within a timeout. The key idea is to call the remote method with a sequence number and a callback and then starting to wait for the response. The remote method calls back with the result and the sequence number. If the response comes within the timeout and its sequence number is the one sent in the method invocation, then the call succeeded. If the response does not come within the timeout then the call failed. Older result received when waiting for the result are ignored.

Typical usage is:


public class MyMethodCaller extends TimeoutRemoteCallHelper {
// The one way remote method to call.
private final IRemoteInterface mTarget;

// One way callback invoked when the remote method is done.
private final IRemoteCallback mCallback = new IRemoteCallback.Stub() {
public void onCompleted(Object result, int sequence) {
onRemoteMethodResult(result, sequence);
}
};

public MyMethodCaller(IRemoteInterface target) {
mTarget = target;
}

public Object onCallMyMethod(Object arg) throws RemoteException {
final int sequence = onBeforeRemoteCall();
mTarget.myMethod(arg, sequence);
return getResultTimed(sequence);
}
}

param
The type of the expected result.
hide

Fields Summary
public static final long
DEFAULT_CALL_TIMEOUT_MILLIS
private static final int
UNDEFINED_SEQUENCE
private final Object
mLock
private final long
mCallTimeoutMillis
private int
mSequenceCounter
private int
mReceivedSequence
private int
mAwaitedSequence
private T
mResult
Constructors Summary
public TimedRemoteCaller(long callTimeoutMillis)


       
        mCallTimeoutMillis = callTimeoutMillis;
    
Methods Summary
public final TgetResultTimed(int sequence)

        synchronized (mLock) {
            final boolean success = waitForResultTimedLocked(sequence);
            if (!success) {
                throw new TimeoutException("No reponse for sequence: " + sequence);
            }
            T result = mResult;
            mResult = null;
            return result;
        }
    
public final intonBeforeRemoteCall()

        synchronized (mLock) {
            mAwaitedSequence = mSequenceCounter++;
            return mAwaitedSequence;
        }
    
public final voidonRemoteMethodResult(T result, int sequence)

        synchronized (mLock) {
            if (sequence == mAwaitedSequence) {
                mReceivedSequence = sequence;
                mResult = result;
                mLock.notifyAll();
            }
        }
    
private booleanwaitForResultTimedLocked(int sequence)

        final long startMillis = SystemClock.uptimeMillis();
        while (true) {
            try {
                if (mReceivedSequence == sequence) {
                    return true;
                }
                final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
                final long waitMillis = mCallTimeoutMillis - elapsedMillis;
                if (waitMillis <= 0) {
                    return false;
                }
                mLock.wait(waitMillis);
            } catch (InterruptedException ie) {
                /* ignore */
            }
        }