android开发文档之Binder、IBinder

翻译一定是站在理解并成功运用的基础上的,同时重视其是否易于读者快速理解核心内容。

下面以android应用工程师的视角进行翻译和注解

android.os.Binder

Binder类时远程对象的基类,是由IBinder定义的轻量级远程程序调用机制(即进程间通信,通信即对象间相互调用彼此的函数、对象等)的核心部分。这个类是IBinder接口的实现,其中IBinder为建立该类的实现提供了标准支持。

大部分开发者不直接实现这个类,而是使用它来生成一个合适的Binder子类,代替使用aidl工具去描述所需要的接口。然而你可以直接集成Binder去实现你自己定制的RPC(Remote Procedure Call Protocol)协议或者简单的实例化一个用来作为进程间共享时的标记的Binder对象。

android.os.IBinder

远程对象的基本接口,在进程内部和进程间执行,是高性能轻量级远程程序呼叫机制的核心部分。这个接口描述了与远程对象互动的抽象协议。不要用直接实现这个接口的方法替代继承Binder类。

IBinder的关键API是和Binder.onTransact()方法相对应的transaction()方法。这些方法分别允许你向IBinder对象发送一个调用和接收一个来自Binder对象的调用。正如transact()方法的调用直到Binder.onTransact()返回结果前不返回结果,这个事务的API是同步执行的;当调用发生在本地进程时,这个行为是显而易见的,当调用发生在进程间时IPC机制会保证同样的效果。

通过transact()发送的数据时Parcel,Parcel是一种数据的通用缓存,除了数据外还带有描述其内容的元数据。元数据被用来管理IBinder对象在缓存中的引用,这样就能使这些引用随缓存跨进程传输。这个机制确保了当一个IBinder被写在一个Parcel中发送到另一个进程时,如果其他进程将同一个IBinder的引用发回给原进程,这时原进程将受到这个IBinder对象的引用。这种机制允许IBinder和Binder对象在跨进程管理时拥有唯一标识。

系统维持一个正在运行的程序维持一个交互线程池。这些线程被用来调度所有即将从其他进程到来的IPC调用。例如,当一个从进程A到进程B的IPC调用生成时,在这个发送事物给B的过程中,发出请求的A线程就堵塞在transact()方法中了。进程B中的交互线程池中的一个线程接收了这个调用,它调用Binder.onTransact(),完成后用一个Parcel来做为结果返回。然后进程A中的那个等待的线程在收到返回的Parcel后得以继续执行。实际上,另一个进程看起来就像是当前进程的一个线程,但不是当前进程创建的。

Binder机制还支持进程间的递归调用。例如,进程A执行自己的IBinder的transact()调用进程B的Binder,而进程B在其Binder.onTransact()中又用transact()向进程A发起调用,那么进程A在等待它发出的调用返回的同时,还会用Binder.onTransact()响应进程B的transact()。总之Binder造成的结果就是让我们感觉到跨进程的调用与进程内的调用没什么区别。

当与使用一个远程对象时,你常常想知道他们何时会失效。这里有三种方法:

1)transact()方法将在IBinder所在晋城不存在的时候抛出RemoteException异常。

2)如果远程进程不存在,将回调pingBinder()方法并返回一个false。

3)linkToDeath()方法可以向IBinder注册一个DeathRecipient方法,在IBinder所在晋城退出时回调。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章