1. IBinder
IBinder是远端对象的基本接口,是轻量级远端过程调用(RPC)机制的核心部分,旨在在进程内和跨进程调用时实现高性能。该接口描述了与远端对象交互的抽象协议。应从Binder扩展该接口,而不能直接实现该接口。
IBinder最关键的API是transact()
和与之相匹配的Binder.onTransact()
。它们可以向IBinder对象发送调用并接收对Binder对象的调用。该API是同步的,因此在Binder.onTransact()
返回之前,transact()
的调用不会返回。这是调用本地进程存在的对象时的预期行为,底层的进程间通信(IPC)机制可确保跨进程时应用这些语义。
通过transact()
发送的数据是Parcel
类型的,Parcel
通用数据缓冲区,还维护一些有关其内容的元数据。元数据用于管理缓冲区中的IBinder对象引用,以便在缓冲区跨进程移动时可以维持这些引用。这种机制确保了,当将IBinder写到Parcel
中并发送到另一个进程时,若另一个进程将对同一个IBinder的引用发送给原进程,则原进程将返回同一个IBinder对象。这些语义允许将IBinder/Binder对象用作可以跨进程管理的唯一标识(用作token或其它目的)。
系统在运行的每个进程中维护一个事务线程池。这些线程用于分发来自其他进程的所有IPC。例如,当从进程A到进程B创建IPC时,A中的调用线程在将事务发送到进程B时在transact()
中阻塞。B中的下一个可用池线程接收到传入的事务,在目标对象上调用Binder.onTransact()
,并返回结果Parcel
。接收到其结果后,进程A中的线程将返回以允许其继续执行。
Binder系统还支持跨进程的递归。例如,如果进程A执行到进程B的事务,并且进程B在处理该事务时对在A中实现的IBinder上的调用transact()
进行了处理,那么当前正在等待原事务完成的进程A中的线程将非常关注进程B调用对象调用Binder.onTransact()
的过程。这确保了调用远端binder对象时的递归语义与调用本地对象时的递归语义相同。
在使用远端对象时,可以通过下面三种方法确定它们何时不再有效:
(1)如果尝试在已不存在的进程的IBinder上调用transact()
方法,则会抛出RemoteException异常。
(2)可以调用pingBinder()
方法,如果远程进程已不存在,则将返回false。
(3)linkToDeath()
方法可用于向IBinder注册DeathRecipient,当进程挂掉时会调用该方法。
1 | // frameworks/base/core/java/android/os/IBinder.java |