本文可能不适于初学者阅读。适于立志于弄懂此领域,并已经进行了相关文章或源码阅读,但未得清晰思路,想要融汇贯通的人,如看过该经典文章innost的Android深入浅出之Binder机制,却被大信息量和分析所淹没思路。~~
一 业务接口IInterface 通信接口IBinder 二者要融合到一块并要能相互转化
IInterface 能力:
asBinder 转化为 Binder 实例 -----转到----> 子类 BnInterface/BpInterface onAsBinder { return this; } 二者是Binder
而IInterface 没有, 跟Binder 没有关系
IBinder 的能力:
getInterfaceDescriptor 知道自己是什么样的接口 借助子类转到IInterface的宏里的实现;
queryLocalInterface(传入的跟自己的比对) BBinder return this; BpBinder --> IBinder return null;
另: inerface_cast --> as_interafce --> queryLocalInterface == null ? .......
IBinder* BnInterface<INTERFACE>::onAsBinder()
{
return this;
}
inline IBinder* BpInterface<INTERFACE>::onAsBinder()
{
return remote();
}
BnInterface == Stub BpInterface == Stub.Proxy
asInterface 静态方法 static 的 像java中的 stub IServiceManager.asInterface()
二 继承关系
Server/Native端
RefBase
|
IInterface (asBinder -> onAsBinder) 业务接口
|
IServiceManager (static asInterface(Binder对象)) 业务接口
|
Bn<IServiceManager> ------ BBinder 通信接口!
|
BnServiceManager (实现业务接口的业务方法) 此对象同java层 IXXXX.Stub
并不是 Bn<IServiceManager>接口, Bn<IServiceManager>只是为了C里多继承, 共用一些逻辑 而设立的
IServiceManager
|
BpInterface<IServiceManager> ----- BpRefBase
|
BpServiceManager 同 IXXXX.Stub.Proxy --- BpRefBase (IBinder* const mRemote)
C 是在 IXXX.h IXXX.cpp 里; 而 java 是在 IXXX.java 里 只不过不是 aidl 代码自动生成
简直有异曲同工之妙 !!!!
三 二者融合 以及的能力(转化)实现
BnInterface 里的 query get 是 IBinder 里的方法 可查:
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor); // return this
virtual const String16& getInterfaceDescriptor() const; //调用父类 IServiceManager:getInterfaceDescriptor IMPLEMENT_META...
protected:
virtual IBinder* onAsBinder();
};
queryLocalInterface getInterfaceDescriptor 在BBinder 里返回的都是null 可以理解 因为是 跟业务相关的。
在BnInterface<IServiceManager> 里实现调用的是IServiceManager里的(即那段宏)
IBinder的接口借由 IServicerManager 中 META_INTERFACE 宏实现
C的多重继承起了作用
IServicerManager ( META_INTERFACE macro: static discriptor, static asInterface, getInterfaceDiscriptor )
/|\
|
N ( Bn<IServiceManager>) <——— (getInterfaceDescriptor, queryLocalInterface(传入的跟自己的比对))
queryLocalInterface 是BBinder(BnXxx实体对象)的接口, 而 BpBinder返回null ;
interface_cast传入的是IBinder : 实际对象是BBinder 或 BpBinder
template<typename INTERFACE>
inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
const String16& _descriptor)
{
if (_descriptor == INTERFACE::descriptor) return this;
return NULL;
}
IBinder :
sp<IInterface> IBinder::queryLocalInterface(const String16& /*descriptor*/)
{
return NULL;
}
IXxxxx接口 借由 onAsBinder return this;
IServicerManager ( asBinder ---转到--- onAsBinder )
|
\|/
P ( Bp<IServiceManager>) ——— (实现onAsBinder return this 因为已经继承Binder了)
二者相互转化的能力 清楚理解的关键
IInterface ----> asBinder + asInterafce(Binder) (实现也是借用了queryLocalInterface)
Binder --> getInterfaceDescriptor + queryLocalInterface(asInterface借用它)
业务接口 能强转成 通信接口; 通信接口 能知道自己是 什么业务接口!!!!!!
由子类来让二者产生关系!!!
四 C Java中 都有这么一套机制,二者的对应关系
另:BpBinder 相当于 java里的 BinderProxy对象
Stub.Proxy 里的 mRemote -----是---- BinderProxy android_util_Binder.cpp 里生成 javaObjectForIBinder 里的mObject 是Binder 应该就是BpBinder对象。 对于 ServiceManager.java sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
---- android_os_BinderInternal_getContextObject ()
------ sp<IBinder> b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b); 跟C层获取方式是一样的!!!
BpServiceManager 里的
(BpRefBase) IBinder* const mRemote; --------- BpBinder 由 ProcessState::self()->getContextObject(NULL); 获得
真是完全对应的啊!!!!
BpBinder(mHandle) BinderProxy(mObject) 让一个handle或地址(是一个整数值) 装扮成 IBinder 对象
mHandler-->BpBinder-->BpServiceManager BpInterface<xxx> 接口
BBinder ------ BpBinder
Binder --------- BinderProxy
IBinder/Binder 对象 Native Remote 对比项
由 handle/地址 ---------> Binder.java BinderProxy------------------------> Stub(native), Proxy 业务对象 JAVA层
BBinder BpBinder -----------------------> BnXxxService BpXxxService C层
五 流程调用
(1)Client端:
BpXxxService.业务接口() ----> BpBinder.transact() --> IPCThreadState::self() --> transact()
( writeTransactionData(写到mOut里) + waitForResponse(while 循环 talkWithDriver(ioctl)) )
writeTransactionData(...., handle,.....) {
binder_transaction_data tr;
tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
tr.target.handle = handle; //BpBinder里的handle
}
如果非要往下说,BpBinder 是怎么对应到 server/remote 端区分的, 就是mHandle字段
(2)Servier端 MediaPlayerService
ProcessState::self()->startThreadPool(); ---> 创建线程 createThreadEtc : _threadLoop
----> threadLoop : IPCThreadState::self()->joinThreadPool(mIsMain); mIsMain为true. (threadLoop return false _threadLoop只执行一次)
--------do { getAndExecuteCommand() } while() //自书己循环执行 Command
------------talkWithDriver + executeCommand //循环执行这个方法
talkWithDriver 跟ioctl打交道 与 mIn 和 mOut 数据交换
把mOut parcel : 写出的数据 mIn parcel : 读取的数据 赋给bwr ioctl 传入驱动中
mOut + mIn bwr <------ioctl-----> binder 驱动
executeCommand
跟mIn mOut 打交道 BBinder -> transact --> onTransact --> BnXxxxxx.onTransact ---> 最终实体对象.业务接口
(3)Servier端 ServiceManager
binder_become_context_manager(bs);
binder_loop(bs, svcmgr_handler);//处理BpServiceManager发过来的命令
for(;;) { res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);}
也是循环
binder_loop ( for(;;) { } ) ----> binder_parse -- > svcmgr_handler ---> do_add_service 添加到链表 svclist