public interface IBinder
Binder
.
The key IBinder API is transact()
matched by
Binder.onTransact()
. These
methods allow you to send a call to an IBinder object and receive a
call coming in to a Binder object, respectively. This transaction API
is synchronous, such that a call to transact()
does not
return until the target has returned from
Binder.onTransact()
; this is the
expected behavior when calling an object that exists in the local
process, and the underlying inter-process communication (IPC) mechanism
ensures that these same semantics apply when going across processes.
The data sent through transact() is a Parcel
, a generic buffer
of data that also maintains some meta-data about its contents. The meta
data is used to manage IBinder object references in the buffer, so that those
references can be maintained as the buffer moves across processes. This
mechanism ensures that when an IBinder is written into a Parcel and sent to
another process, if that other process sends a reference to that same IBinder
back to the original process, then the original process will receive the
same IBinder object back. These semantics allow IBinder/Binder objects to
be used as a unique identity (to serve as a token or for other purposes)
that can be managed across processes.
The system maintains a pool of transaction threads in each process that it runs in. These threads are used to dispatch all IPCs coming in from other processes. For example, when an IPC is made from process A to process B, the calling thread in A blocks in transact() as it sends the transaction to process B. The next available pool thread in B receives the incoming transaction, calls Binder.onTransact() on the target object, and replies with the result Parcel. Upon receiving its result, the thread in process A returns to allow its execution to continue. In effect, other processes appear to use as additional threads that you did not create executing in your own process.
The Binder system also supports recursion across processes. For example if process A performs a transaction to process B, and process B while handling that transaction calls transact() on an IBinder that is implemented in A, then the thread in A that is currently waiting for the original transaction to finish will take care of calling Binder.onTransact() on the object being called by B. This ensures that the recursion semantics when calling remote binder object are the same as when calling local objects.
When working with remote objects, you often want to find out when they are no longer valid. There are three ways this can be determined:
transact()
method will throw a
RemoteException
exception if you try to call it on an IBinder
whose process no longer exists.
pingBinder()
method can be called, and will return false
if the remote process no longer exists.
linkToDeath()
method can be used to register
a IBinder.DeathRecipient
with the IBinder, which will be called when its
containing process goes away.
Binder
Modifier and Type | Interface and Description |
---|---|
static interface |
IBinder.DeathRecipient
Interface for receiving a callback when the process hosting an IBinder
has gone away.
|
Modifier and Type | Field and Description |
---|---|
static int |
DUMP_TRANSACTION
IBinder protocol transaction code: dump internal state.
|
static int |
FIRST_CALL_TRANSACTION
The first transaction code available for user commands.
|
static int |
FLAG_ONEWAY
Flag to
transact(int, android.os.Parcel, android.os.Parcel, int) : this is a one-way call, meaning that the
caller returns immediately, without waiting for a result from the
callee. |
static int |
INTERFACE_TRANSACTION
IBinder protocol transaction code: interrogate the recipient side
of the transaction for its canonical interface descriptor.
|
static int |
LAST_CALL_TRANSACTION
The last transaction code available for user commands.
|
static int |
LIKE_TRANSACTION
IBinder protocol transaction code: tell an app asynchronously that the
caller likes it.
|
static int |
PING_TRANSACTION
IBinder protocol transaction code: pingBinder().
|
static int |
SYSPROPS_TRANSACTION |
static int |
TWEET_TRANSACTION
IBinder protocol transaction code: send a tweet to the target
object.
|
Modifier and Type | Method and Description |
---|---|
void |
dump(FileDescriptor fd,
String[] args)
Print the object's state into the given stream.
|
void |
dumpAsync(FileDescriptor fd,
String[] args)
Like
dump(FileDescriptor, String[]) but always executes
asynchronously. |
String |
getInterfaceDescriptor()
Get the canonical name of the interface supported by this binder.
|
boolean |
isBinderAlive()
Check to see if the process that the binder is in is still alive.
|
void |
linkToDeath(IBinder.DeathRecipient recipient,
int flags)
Register the recipient for a notification if this binder
goes away.
|
boolean |
pingBinder()
Check to see if the object still exists.
|
IInterface |
queryLocalInterface(String descriptor)
Attempt to retrieve a local implementation of an interface
for this Binder object.
|
boolean |
transact(int code,
Parcel data,
Parcel reply,
int flags)
Perform a generic operation with the object.
|
boolean |
unlinkToDeath(IBinder.DeathRecipient recipient,
int flags)
Remove a previously registered death notification.
|
static final int FIRST_CALL_TRANSACTION
static final int LAST_CALL_TRANSACTION
static final int PING_TRANSACTION
static final int DUMP_TRANSACTION
static final int INTERFACE_TRANSACTION
static final int TWEET_TRANSACTION
Build.VERSION_CODES.HONEYCOMB_MR2
, all Binder objects are
expected to support this protocol for fully integrated tweeting
across the platform. To support older code, the default implementation
logs the tweet to the main log as a simple emulation of broadcasting
it publicly over the Internet.
Also, upon completing the dispatch, the object must make a cup of tea, return it to the caller, and exclaim "jolly good message old boy!".
static final int LIKE_TRANSACTION
There is no response returned and nothing about the system will be functionally affected by it, but it will improve the app's self-esteem.
static final int SYSPROPS_TRANSACTION
static final int FLAG_ONEWAY
transact(int, android.os.Parcel, android.os.Parcel, int)
: this is a one-way call, meaning that the
caller returns immediately, without waiting for a result from the
callee. Applies only if the caller and callee are in different
processes.String getInterfaceDescriptor() throws RemoteException
RemoteException
boolean pingBinder()
boolean isBinderAlive()
IInterface queryLocalInterface(String descriptor)
void dump(FileDescriptor fd, String[] args) throws RemoteException
fd
- The raw file descriptor that the dump is being sent to.args
- additional arguments to the dump request.RemoteException
void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException
dump(FileDescriptor, String[])
but always executes
asynchronously. If the object is local, a new thread is created
to perform the dump.fd
- The raw file descriptor that the dump is being sent to.args
- additional arguments to the dump request.RemoteException
boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException
code
- The action to perform. This should
be a number between FIRST_CALL_TRANSACTION
and
LAST_CALL_TRANSACTION
.data
- Marshalled data to send to the target. Must not be null.
If you are not sending any data, you must create an empty Parcel
that is given here.reply
- Marshalled data to be received from the target. May be
null if you are not interested in the return value.flags
- Additional operation flags. Either 0 for a normal
RPC, or FLAG_ONEWAY
for a one-way RPC.RemoteException
void linkToDeath(IBinder.DeathRecipient recipient, int flags) throws RemoteException
IBinder.DeathRecipient
's
DeathRecipient.binderDied()
method
will be called.
You will only receive death notifications for remote binders, as local binders by definition can't die without you dying as well.
Throws
- RemoteException
if the target IBinder's
process has already died.RemoteException
unlinkToDeath(android.os.IBinder.DeathRecipient, int)
boolean unlinkToDeath(IBinder.DeathRecipient recipient, int flags)
DeathRecipient.binderDied()
method
will not be called. Returns false if the target IBinder has already
died, meaning the method has been (or soon will be) called.Throws
- NoSuchElementException
if the given
recipient has not been registered with the IBinder, and
the IBinder is still alive. Note that if the recipient
was never registered, but the IBinder has already died, then this
exception will not be thrown, and you will receive a false
return value instead.