前言
阅读Android源码时总是遇到Bnxx和Bpxx等类,老是对不上号,容易迷糊,因此这里记录一下,方便自己查阅。
正文
BP(binder proxy)和BN(binder native)是通过binder来通信的,Bp端可以通过BinderProxy的transact()方法与Bn端发送请求,而Bn端通过继承Binder类并重写onTransact()接收并处理来自Bp端的请求。
两端会实现相同的接口,但Proxy端只是通过binder ipc发送一个binder transaction,native端是真正做事情,再将结果返回。
Bn
n 就是native,给server用。
继承是为了实现一个接口,就是一个BnXX对应一个IXX。
I 就是interface(接口)
Bp
p 就是proxy代理,给client用的。
这个存在的意义在于通过IPC机制去实现执行接口函数调用,同样一个BpXX对应一个IXX。
例子
涉及的代码块
\frameworks\av\media\libmedia\IMediaPlayer.cpp \frameworks\av\media\libmedia\include\media\IMediaPlayer.h
这里只要介绍BnMediaPlayer和BpMediaPlayer。
BnMediaPlayer
class BnMediaPlayer: public BnInterface<IMediaPlayer> { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); };
BpMediaPlayer
class BpMediaPlayer: public BpInterface<IMediaPlayer> { //略 }
在代码中,客户端通过BpMediaPlayer发送消息,然后BnMediaPlayer接收,然后调用服务端进行处理。
setDataSource
以setDataSource()为例。
# BpMediaPlayer中的方法 status_t setDataSource(int fd, int64_t offset, int64_t length) { //略 //通过binder,remote()就是一个binder remote()->transact(SET_DATA_SOURCE_FD, data, &reply); return reply.readInt32(); }
目前对binder不是很理解,但通过网上文章和自己跟踪,remote()->transact(SET_DATA_SOURCE_FD, data, &reply)通过Binder,最后进入了BnMediaPlayer的onTransact()方法。
status_t BnMediaPlayer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ switch (code) { //略 case SET_DATA_SOURCE_FD: { CHECK_INTERFACE(IMediaPlayer, data, reply); //略 // MediaPlayerService中的Client继承BnMediaPlayer //这里的setDataSource是MediaPlayerService::Client::setDataSource。 reply->writeInt32(setDataSource(fd, offset, length)); return NO_ERROR; } //略 } }
当然,真正处理的还是MediaPlayerService::Client::setDataSource()方法。
从上面可以看出
-
B就是Binder
-
Bnxx给Server用的
-
Bpxx是个Client用的
-
Bpxx可以通过BinderProxy的transact()方法与Bnxxx发送请求,而Bnxx通过继承Binder类并重写onTransact()接收并处理来自Bpxx的请求。
参考文章
-
《》
-
《》
-
《》
-
《》