2.2 Java层中的Binder架构分析
2.2.1 Binder架构总览
如果读者读过卷I第6章“深入理解Binder”,相信就不会对Binder架构中代表Client的Bp端及代表Server的Bn端感到陌生。Java层中Binder实际上也是一个C/S架构,而且其在类的命名上尽量保持与Native层一致,因此可认为,Java层的Binder架构是Native层Binder架构的一个镜像。Java层的Binder架构中的成员如图2-1所示。
图 2-1 Java层中的Binder家族
由图2-1可知:
系统定义了一个IBinder接口类以及DeathRecipient接口。
Binder类和BinderProxy类分别实现了IBinder接口。其中,Binder类作为服务端的Bn的代表,而BinderProxy作为客户端的Bp的代表。
系统中还定义了一个BinderInternal类。该类是一个仅供Binder架构使用的类。它内部有一个GcWatcher类,该类专门用于处理和Binder架构相关的垃圾回收。
Java层同样提供一个用于承载通信数据的Parcel类。
注意,IBinder接口类中定义了一个名为FLAG_ONEWAY的整型变量,该变量的意义非常重要。当客户端利用Binder机制发起一个跨进程的函数调用时,调用方(即客户端)一般会阻塞,直到服务端返回结果。这种方式和普通的函数调用是一样的。但是在调用Binder函数时,如果指明了FLAG_ONEWAY标志,则调用方只要把请求发送到Binder驱动即可返回,而不用等待服务端的结果,这就是一种所谓的非阻塞方式。在Native层中,涉及的Binder调用基本都是阻塞的,但是在Java层的framework中,使用FLAG_ONEWAY进行Binder调用的情况非常多,以后经常会碰到。
思考 使用FLAG_ONEWAY进行函数调用的程序在设计上有什么特点?这里简单分析一下:对于使用FLAG_ONEWAY的函数来说,客户端仅向服务端发出了请求,但是并不能确定服务端是否处理了该请求。所以,客户端一般会向服务端注册一个回调(同样是跨进程的Binder调用),一旦服务端处理了该请求,就会调用此回调函数来通知客户端处理结果。当然,这种回调函数也大多采用FLAG_ONEWAY的方式。