前几张我们已经介绍了Binder通信从驱动层到Java层,但是我们还是感觉模模糊糊,所以写一篇文章专门理清楚Binder的关系。那这篇文章和之前写的Binder文章有什么不同呢?
主要有以下几点不同!
- 这篇文章目的并不是以大量的代码为主,而是说明每个类还有核心方法的说明,然后进行组装。
- 这篇文章尽可能少写或者不写驱动层,关于驱动层已经在Binder驱动那两篇文章中详细说明。
C/S架构的基本理解
首先大家都知道Binder是Android中IPC通信的机制,Android是基于Linux内核的,当然也有其他通信方式,但是为什么还要用Binder呢?就是因为Binder更加灵活,通过Binder可以将其他的部分连接起来。
Clinet和Server端是C/S架构的标准模型,但是Android还有一个ServerManager,他的功能是管理系统中各种服务。他们之间的关系就和三角恋一样。
1.Client注册一些Service到ServerManager中,在这个模型中Clinet端就是C,ServerManager端就是S
2.Service要注册到ServerManager中,在这个模型中Service就是C,ServerManager端就是S
3.Client和Server通信,那么Client就是C,Server就是S
服务的注册过程
ProcessState是在系统中唯一的,它是以单例模式存在的。他的使命就是打开Binder设备,分配Binder所需要的内存。
ProcessState.cpp
//调用下面
sp<ProcessState> proc(ProcessState::self());
ProcessState::ProcessState()
: mDriverFD(open_driver())//打开设备
...
{
...
}
static int open_driver()
{
int fd = open("/dev/binder", O_RDWR);
...
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);//BINDER_SET_MAX_THREADS=15
}
sp<ProcessState> ProcessState::self()
{
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState;
return gProcess;
}
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
...
return new BpBinder(handle);
}
IServiceManager
IServiceManager.cpp
//调用下面
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
通过在ProcessState模块中查找,然后我们发现和下面代码等同
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
最后我们通过模板方法还原,得出
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
等价于:
gDefaultServiceManager = new BpServiceManager(new BpBinder(0));
然后我们就说下BpBinder,BBbinder,IServiceManager,BpServiceManager他们之间有什么关系。
BpBinder
这个类并没有操作ProcessState打开的Binder设备,他也是间接和驱动打交道。主要是通过IPCThreadState::self()->transact()
这个方法才是真正和驱动打交道的方法。所以我们等会要说IPCThreadState
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
IServiceManager小家庭
IServiceManager真正起作用的是派生类BpServiceManager
和BnServiceManager
这两个类的关系就是代理模式之间的关系里面通过管理BpBinder和BBinder对象的操作。具体操作有:
getService()
,checkService()
,addService()
,listServices()
在这些方法中基本都是调用:
remote()->transact(XXX, data, &reply);
对于BpServiceManager其中remote()是BpBinder,对于BnServiceManager是那些系统服务的父类(MediaPlayerService…)因为这些服务本身就是Binder。
IPCThreadState
这个类也是单例模式,这个类就是实现通信的基础中的基础。
其中handle就是目标进程
status_t IPCThreadState::transact(...)
{
...
//BC_TRANSACTION是程序给Binder设备发送信息的消息码。回复信息用BR_
//数据封装的标准是binder_transaction_data结构体
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
...
err = waitForResponse(reply);
...
return err;
}
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
cmd = (uint32_t)mIn.readInt32();
switch (cmd) {
...
default:
err = executeCommand(cmd);
break;
}
}
return err;
}
写数据
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
...
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
...
bwr.write_consumed = 0;
bwr.read_consumed = 0;
do {
#if defined(HAVE_ANDROID_OS)
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)//调用ioctl读取数据
err = NO_ERROR;
else
err = -errno;
#else
} while (err == -EINTR);
if (err >= NO_ERROR) {
if (bwr.read_consumed > 0) {
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
}
return NO_ERROR;
}
return err;
}
读数据
status_t IPCThreadState::executeCommand(int32_t cmd)
{
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch ((uint32_t)cmd) {
...
case BR_TRANSACTION:
{
binder_transaction_data tr;
result = mIn.read(&tr, sizeof(tr));
...
if (tr.target.ptr) {
sp<BBinder> b((BBinder*)tr.cookie);
error = b->transact(tr.code, buffer, &reply, tr.flags);
} else {
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
...
}
break;
...
}
return result;
}
看到这里我们就知道了真正和驱动打交道的就是IPCThreadState,单例模式,然后放到BpBinder中操作,BpBinder又被BpServiceManager管理。
这些BpXXX都对应到服务端是BnXXX除了BpBinder对应BBinder,我也不知道谷歌怎么想的鸟名字不叫BnBinder。
那么我们就问了,那BBinder干啥?
由于其中BpBinder可以调用到BpBinder::transact()->IPCThreadState::self()->transact()
和驱动进行通信.这个方法会调用到IPCThreadState::executeCommand()
这个方法会调用
sp<BBinder> b((BBinder*)tr.cookie);
error = b->transact(tr.code, buffer, &reply, tr.flags);
其中b->transact()会调用onTransact()这里注意b是BBinder我们在java代码中看到是JavaBBinder继承与BBinder,所以此时会调用JavaBBinder的onTransact(),在这个回调函数中我们将可以看到调用execTransact(),然后我们在Binder.java的execTransact()方法中看到又调用Binder.java的onTransact()方法,所以回调了我们生成的aidl文件中的onTransact()方法。