public abstract class OneWayBinderProxy
extends java.lang.Object
IBinder with a safe and uniformly asynchronous transaction API.
When the target of your bindService() call is hosted in a different process, Android supplies
you with an IBinder that proxies your transactions to the remote Binder instance. But when the target Service is hosted in the same process, Android
supplies you with that local instance of Binder directly. This in-process
implementation of IBinder is problematic for clients that want "oneway" transaction
semantics because its transact() method simply invokes onTransact() on the caller's thread, even
when the IBinder.FLAG_ONEWAY flag is set. Even though this behavior is documented, its
consequences with respect to reentrancy, locking, and transaction dispatch order can be
surprising and dangerous.
Wrap your IBinders with an instance of this class to ensure the following
out-of-process "oneway" semantics are always in effect:
NB: One difference that this class can't conceal is that calls to onTransact() are serialized
per OneWayBinderProxy instance, not per instance of the wrapped IBinder. An
android.os.Binder with in-process callers could still receive concurrent calls to onTransact() on
different threads if callers used different OneWayBinderProxy instances or if that Binder
also had out-of-process callers.
| Modifier and Type | Field and Description |
|---|---|
protected android.os.IBinder |
delegate |
| Modifier and Type | Method and Description |
|---|---|
android.os.IBinder |
getDelegate()
Returns the wrapped
IBinder for the purpose of calling methods other than IBinder.transact(int, Parcel, Parcel, int). |
abstract void |
transact(int code,
io.grpc.binder.internal.ParcelHolder data)
Enqueues a transaction for the wrapped
IBinder with guaranteed "oneway" semantics. |
protected boolean |
transactAndRecycleParcel(int code,
android.os.Parcel data) |
static OneWayBinderProxy |
wrap(android.os.IBinder iBinder,
java.util.concurrent.Executor inProcessThreadHopExecutor)
Returns a new instance of
OneWayBinderProxy that wraps iBinder. |
public static OneWayBinderProxy wrap(android.os.IBinder iBinder, java.util.concurrent.Executor inProcessThreadHopExecutor)
OneWayBinderProxy that wraps iBinder.iBinder - the binder to wrapinProcessThreadHopExecutor - a non-direct Executor used to dispatch calls to onTransact(),
if necessaryOneWayBinderProxypublic abstract void transact(int code,
io.grpc.binder.internal.ParcelHolder data)
throws android.os.RemoteException
IBinder with guaranteed "oneway" semantics.
NB: Unlike IBinder.transact(int, android.os.Parcel, android.os.Parcel, int), implementations of this method take ownership of the
data Parcel. When this method returns, data will normally be empty, but callers
should still unconditionally ParcelHolder.close() it to avoid a leak in case they or
the implementation throws before ownership is transferred.
code - identifies the type of this transactiondata - a non-empty container of the Parcel to be sentandroid.os.RemoteException - if the transaction could not even be queued for dispatch on the server.
Failures from Binder.onTransact(int, android.os.Parcel, android.os.Parcel, int) are *never* reported this way.public android.os.IBinder getDelegate()
IBinder for the purpose of calling methods other than IBinder.transact(int, Parcel, Parcel, int).protected boolean transactAndRecycleParcel(int code,
android.os.Parcel data)
throws android.os.RemoteException
android.os.RemoteException