Binder学习笔记(六)—— binder服务端是如何组织addService数据的
在checkService的调查中我们知道客户端向ServiceManager请求服务名,ServiceManager根据服务名遍历本地链表,找到匹配的handle返回给客户端。这个handle显然是由服务端注册的,这个handle究竟是什么?要先搞清楚这个问题,必须研究服务端和ServiceManager是如何共同完成一次addService操作的。我们从服务端代码出发。TestService.cpp:30
int main() {
sp < ProcessState > proc(ProcessState::self());
sp < IServiceManager > sm = defaultServiceManager();
// sm = new BpServiceManager(new BpBinder(0))
sm->addService(String16("service.testservice"), new BnTestService());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return ;
}
在《defaultServiceManager()返回了什么?》一文中已经知道,sm就是new BpServiceManager(new BpBinder( 0 ) ),因此,找到BpServiceManager::addService(…),frameworks/native/libs/binder/IServiceManager.cpp:155
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{ // name="service.testservice", service=new BnTestService(),allowIsolated=false
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? : );
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
Parcel的数据组织规则参见《Parcel是怎么打包的?》。这里打包的service是由main函数传入的new BnTestService(),它的类型是remote还是local呢?从命名上来看我猜是local(BpXXX代表proxy,BnXXX代表native)。来看看BnTestService的继承关系:BnTestService继承自BnInterface<ITestService>,BnInterface继承自BBinder,BBinder覆盖了虚函数localBinder(){return this;}在Binder.cpp:191。因此这个Parcel data的示意图为:

binder->localBinder()返回binder的this指针,因此就是传入的service参数,即new BnTestService()。
接下来在BpServiceManager::addService(…)函数中调用remote()->transact(…)组织数据的过程在《binder客户端是如何组织checkService数据》中已经分析过了,不再详细解释,只列出关键节点:
frameworks/native/libs/binder/IServiceManager.cpp:155
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{ // name="service.testservice", service=new BnTestService(),allowIsolated=false
Parcel data, reply;
……
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
……
}
frameworks/native/libs/binder/BpBinder.cpp:159
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{ // code=ADD_SERVICE_TRANSACTION, flags=0
// Once a binder has died, it will never come back to life.
……
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
……
}
frameworks/native/libs/binder/IPCThreadState.cpp:548
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{ // handle=0, code=ADD_SERVICE_TRANSACTION, flags=0
status_t err = data.errorCheck(); flags |= TF_ACCEPT_FDS;
……
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
……
return err;
}
frameworks/native/libs/binder/IPCThreadState.cpp:904
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{ // cmd=BC_TRANSACTION, binderFlags=TF_ACCEPT_FDS, handle=0,
// code=ADD_SERVICE_TRANSACTION,
binder_transaction_data tr; tr.target.ptr = ; /* Don't pass uninitialized stack data to a remote process */
tr.target.handle = handle;
tr.code = code;
tr.flags = binderFlags;
tr.cookie = ;
tr.sender_pid = ;
tr.sender_euid = ;
……
tr.data_size = data.ipcDataSize();
tr.data.ptr.buffer = data.ipcData();
tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
tr.data.ptr.offsets = data.ipcObjects();
……
mOut.writeInt32(cmd);
mOut.write(&tr, sizeof(tr)); return NO_ERROR;
}
它组织成最终的请求数据为:

Binder学习笔记(六)—— binder服务端是如何组织addService数据的的更多相关文章
- # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)
目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...
- Netty学习笔记(二) 实现服务端和客户端
在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...
- 《精通并发与Netty》学习笔记(02 - 服务端程序编写)
上节我们介绍了开发netty项目所必需的开发环境及工具的使用,这节我们来写第一个netty项目 开发步骤 第一步:打开https://search.maven.org 找到netty依赖库 第二步:打 ...
- Kafka学习笔记2--Kafka的服务端配置
下载解压 kafka 后,在 kafka/config 下有 3 个配置文件与主题的生产.消费相关. server.properties--服务端配置 producer.properties--生产端 ...
- 红帽学习笔记[RHCE]OpenLDAP 服务端与客户端配置
目录 OpenLDAP 服务端与客户端配置 关于LDIF 一个LDIF基本结构一个条目 属性 Object的类型 服务端 安装 生成证书 生成默认数据 修改基本的配置 导入基础数据 关于ldif的格式 ...
- Binder学习笔记(九)—— 服务端如何响应Test()请求 ?
从服务端代码出发,TestServer.cpp int main() { sp < ProcessState > proc(ProcessState::self()); sp < I ...
- Binder学习笔记(八)—— 客户端如何组织Test()请求 ?
还从客户端代码看起TestClient.cpp:14 int main() { sp < IServiceManager > sm = defaultServiceManager(); / ...
- Binder学习笔记(十二)—— binder_transaction(...)都干了什么?
binder_open(...)都干了什么? 在回答binder_transaction(...)之前,还有一些基础设施要去探究,比如binder_open(...),binder_mmap(...) ...
- Binder学习笔记(五)—— Parcel是怎么打包数据的?
前文中曾经遇到过Parcel,从命名上知道他负责数据打包.在checkService的请求/响应体系中,Parcel只打包了基本数据类型,如Int32.String16……后面还要用于打包抽象数据类型 ...
随机推荐
- laravel 对于ajax请求返回的数据
ajax在调试器中的位置 XHR 代表 XMlHTTPREQUET 一般ajax请求php的时候我们需要给返回什么数据呢? 一般我都是直接renturn 数组的 其实也没啥问题 但是还是感觉第三种写 ...
- DBUtils使用BeanListHandler及BeanHandler时返回null
一.使用Bean相关方法时返回null 问题描述: 使用DBUtils查询数据,如果使用ArrayListHandler等都能够返回正确值,但使用BeanListHandler 和 BeanHandl ...
- maven学习6 Eclipse下Tomcat常用设置
Eclipse下Tomcat常用设置 1,Eclipse建立Tomcat服务 1.1 新建Server 首先这里是指,jee版的Eclipse.Eclipse是没有像MyEclipse那样集成Tomc ...
- 数据库:sql语句分别按日,按周,按月,按季统计金额
如: 表:consume_record 字段:consume (money类型) date (datetime类型) 请问怎么写四条sql语句分别按日,按周,按月,按季统计消费总量. 如:1月 120 ...
- 2015.3.7 Dll CString不能作为传入参数而要用char*
extern "C" __declspec(dllexport) void CalcArc_2(Point2D& pm, double am, double an, CSt ...
- 基于候选区域的深度学习目标检测算法R-CNN,Fast R-CNN,Faster R-CNN
参考文献 [1]Rich feature hierarchies for accurate object detection and semantic segmentation [2]Fast R-C ...
- 杀死tomcat进程
由于tomcat运行时eclipse非法关闭,导致tomcat进程没有关闭,再次启动eclipse,启动tomcat会报tomcat不能启动,且指出端口被占用.笔者解决方案如下: 方案一:重启电脑,简 ...
- C语言学习笔记--内存操作常见错误
1. 野指针 (1)指针变量中的值是非法的内存地址,进而形成野指针 (2)野指针不是 NULL 指针,是指向不可用内存地址的指针 (3)NULL 指针并无危害,很好判断,也很好调试 (4)C 语言中无 ...
- Go并发原理
Go语言是为并发而生的语言,Go语言是为数不多的在语言层面实现并发的语言:也正是Go语言的并发特性,吸引了全球无数的开发者. 并发(concurrency)和并行(parallellism) 并发(c ...
- pthon之函数式编程
函数式编程是一种抽象计算的编程范式. 不同语言的抽象层次不同:计算机硬件->汇编语言->C语言->Python语言 指令 -> ->函数 ...