Android - Binder机制 - 普通service注册

本文深入剖析 Android 系统中 Binder 机制下服务的注册过程,从 Main_mediaserver 进程初始化到 CameraService 注册,详细解读涉及的关键类及其交互方式。

以下几篇文章是较深入分析binder机制。

目录

1. Android - Binder机制 - ServiceManager

2. Android - Binder机制 - 普通service注册

3. Android - Binder机制 - 获得普通service

4. Android - Binder机制 - client和普通service交互

5. Android - Binder机制 - Binder框架总结

6. Android - Binder机制 - ProcessState和IPCThreadState

7. Android - Binder机制 - 驱动


Android - Binder机制 - 普通service注册

UML及说明


这个要比ServiceManager复杂多了,首先对每个类进行简单角色说明:

1. Main_mediaserver是一个进程,它是多媒体方面的总进程,这个进程共开启了MediaPlayerService等四个服务,我们这篇讲的就是如何注册一个服务;

2. Service_manager.c就是第一篇将的ServiceManager,它是另外一个进程,它要通过binder接收该进程的AddService请求,并进行相应处理(第一篇已经讲);

3. IInterface和IServiceManager定义了Main_mediaserver和ServiceManager之间的功能接口,它是一个抽象类;

4. BpServiceManager和BpInterface继承于IServiceManager,当然就是对功能接口的具体实现;

5. CameraService是照相机的服务,它继承于BinderService,它主要是调用BpServiceManager的addService()接口注册服务;

6. IBinder是定义Binder数据传输层的功能接口,它有一个接口transact,做过android的应该都有印象,它也是一个抽象类;

7. BpBinder是对IBinder的具体实现,它是用来进行数据传输的,BpRefBase中的mRemote就是指向的BpBinder,BpRefBase起了一个代理作用,但是BpBinder没有直接和binder打交道,而是通过调用下面的IPCThreadState实现的;

8. IPCThreadState才是和binder进行打交道的类,它才是真正的数据传输者;

9. ProcessState它主要打开binder设备供IPCThreadState使用和获得ServiceManager用来注册服务;

10. 在分析的时候还是先有一个整体把握,这个会在后面详解,BpRefBase以上是业务逻辑(要实现什么功能),BpRefBase以下是数据传输(通过binder如何将功能实现);

11. 以后只要是见到Bpxxx的是在client进程,Bnxxx的是在service进程;


Main_mediaserver初始化

int main(int argc, char** argv)
{
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    AudioFlinger::instantiate();
    MediaPlayerService::instantiate();
    CameraService::instantiate();
    AudioPolicyService::instantiate();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

主要进行以下几步:

1. 创建ProcessState,每个进程就一个ProcessState;

2. 获得ServiceManager,defaultServiceManager()返回的其实是BpServiceManager,在new BpServiceManager时,传入的参数其实就是BpBinder,逐步保存在了BpRefBase中的mRemote中,而这个BpBinder的mHandle是0,这个0就是ServiceManager的索引值;

3. 注册各个服务,在后面详细说明;

4. ProcessState::self()->startThreadPool()和IPCThreadState::self()->joinThreadPool(),这俩是开启两个线程,这两个线程其实完成同样的工作,就是检测是否有发往binder的数据和binder有没有数据发来,这在以后篇章详细讲解,本篇在关系到这两类时会简单说明;

这个进程就开始工作了,它提供了四个服务,下面详细说明如何注册一个服务。


CameraService注册服务

1. BinderService通过defaultServiceManager()->addService(String16(SERVICE::getServiceName()), new SERVICE());

2. defaultServiceManager其实是BpServiceManager,addService则执行remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

3. remote()其实是BpBinder,transact执行IPCThreadState::self()->transact(mHandle, code, data, reply, flags),注意mHandle是0,代表ServiceManager;

4. IPCThreadState::self()->transact执行writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL)和waitForResponse(reply),很明显就是发送数据,然后等待响应;

5. writeTransactionData其实并不直接将数据发送到binder驱动,而是将数据写到了mOut缓冲区,mOut是Parcel,该类是封装和驱动交互数据的数据格式(如果精通binder,要清楚这个格式);

6. waitForResponse调用talkWithDriver()获得binder的答复;

至此,基本经过六步,注册服务就完成了,这里只是介绍了简单的工作流程。

<think>嗯,用户现在想了解Android Binder机制的工作流程和架构图。之前我已经给出了Binder机制的详细介绍,但用户似乎更关注具体的实现流程和可视化结构。需要结合三个引用内容来组织答案,特别是引用[2]提到了分层架构图,这个很关键。 用户提供的引用中,引用[1]提到Binder类实现IBinder接口,引用[2]强调分层设计,引用[3]补充了进程通信背景。应该重点突出这些内容:首先说明BinderAndroid架构中的位置(应用层/Framework层/Native层/内核层),然后用流程图展示跨进程调用过程,最后解释核心组件如Binder驱动、ServiceManager的作用。 考虑到用户上次问题中的"架构图"需求,需要绘制分层示意图。不过用户要求用mermaid格式,这正好可以清晰展示从Java到内核的调用链。同时要补充工作流程的四个关键阶段:客户端调用、驱动转发、服务处理、结果返回,每个阶段对应到具体代码实现层面,比如Java层的AIDL Stub和Native层的BpBinder。 注意到用户可能混淆了Binder机制普通Linux IPC的区别,在回答最后补充相关问题时会专门设计SHM对比的题目。另外用户引用的资料提到数据大小限制,这也要在问题列表里体现。 需要严格检查技术细节:1)Binder驱动mmap的实现位置在kernel层 2)ServiceManager作为上下文管理者的注册过程 3)AIDL编译后生成的Proxy/Stub类结构。这些在架构图中都要用不同颜色区分层级。 </think>以下是Android Binder机制的工作流程详解及分层架构图: --- ### **一、Binder分层架构图** ```mermaid graph TD A[应用层] -->|AIDL接口调用| B(Java Framework) B -->|JNI| C[Native层 libbinder.so] C -->|ioctl| D[Kernel层 /dev/binder驱动] D -->|跨进程路由| E[Native层 libbinder.so] E -->|JNI| F(Java Framework) F -->|Binder对象| G[服务端应用] ``` | **层级** | **核心组件** | **作用** | |------------------|---------------------------------------|-------------------------------------------------------------------------| | **应用层** | AIDL接口、`IBinder` | 开发者直接使用的API,封装跨进程调用逻辑[^1] | | **Java Framework**| `ServiceManager`、`BinderProxy` | 管理服务注册/发现,生成客户端代理类 | | **Native层** | `libbinder.so`、`BnBinder`/`BpBinder` | 实现IPC核心逻辑,处理数据序列化/反序列化[^2] | | **Kernel层** | Binder驱动(`/dev/binder`) | 进程间路由、内存映射管理、线程调度[^3] | --- ### **二、Binder工作流程** 以客户端调用服务端方法为例: 1. **客户端发起请求** ```java // 应用层代码 IMyService service = IMyService.Stub.asInterface(binder); int result = service.add(3, 5); // 跨进程调用 ``` - 通过AIDL生成的`Proxy`类将请求打包为`Parcel`对象[^1] 2. **数据传递至内核** - `BpBinder`(Native层客户端代理)通过`ioctl()`系统调用将数据发送到Binder驱动 - 驱动通过**一次拷贝**完成数据传递(利用`mmap`内存映射)[^3]: $$ \text{Client进程用户空间} \xrightarrow{\text{mmap}} \text{内核缓冲区} \xrightarrow{\text{直接映射}} \text{Server进程用户空间} $$ 3. **服务端处理请求** ```c // Native层BnBinder实现 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply) { switch(code) { case ADD: int a = data.readInt(); int b = data.readInt(); reply->writeInt(a + b); // 结果写入Parcel return NO_ERROR; } } ``` 4. **结果返回客户端** - 驱动将结果Parcel路由回客户端进程 - 客户端`Proxy`类解析结果并返回给应用层 --- ### **三、关键组件协作** | **组件** | **角色** | |--------------------|-------------------------------------| | `ServiceManager` | 服务的DNS系统,管理Binder实名注册[^2] | | `Binder驱动` | 跨进程通信路由器,管理线程池 | | `Binder线程池` | 每个进程维护的IPC处理线程(默认16个)| --- ### **四、性能优化设计** 1. **单次数据拷贝** Binder驱动通过`mmap`在内核开辟共享缓冲区: - 发送方:数据从**用户空间→内核缓冲区** - 接收方:内核缓冲区**直接映射**到其用户空间 *对比传统IPC(如Socket需2次拷贝)* 2. **引用计数机制** $$ \text{对象生命周期} = f(\text{强引用计数}, \text{弱引用计数}) $$ - 驱动跟踪跨进程对象引用,避免内存泄漏 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值