Binder里面的关系分析

前几张我们已经介绍了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真正起作用的是派生类BpServiceManagerBnServiceManager这两个类的关系就是代理模式之间的关系里面通过管理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()方法。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值