binder-LinkToDeath

Pmcs类图理解

1. 名词定义

名词 含义
BBinder 服务端接口
BpBinder 客户端接口

2. 使用Binder流程

  • 开发native service
    1. 定义服务端接口文件,即IPmcsService类,其继承于IInterface类
    2. 定义BnPmcsService类,继承于BnInterface
    3. 实现一个PmcsService类,继承于BnPmcsService类,并实现响应客户端请求onTransact()
  • 开发client

BpBinder(客户端)如何把请求发送给BBinder(服务端),BBinder又如何将响应传回给客户端的呢?

3. BBinder服务端

服务端类

  • BBinder 实现了大部分的IBinder 接口,除了onTransact() 和 queryLocalInterface(), getInterfaceDescriptor()
  • IInterface
    • 实现queryLocalInterface(),该函数可查询服务端提供的服务
    • INTERFACE模板继承和实现IInterface
  • BnInterface
    • BnInterface 对象将自己强制转换成 IInterface对象返回给客户端
    • BnInterface是一个模板类,继承了BBinder和模板INTERFACE
    • BnInterface 实现了IBinder的queryLocalInterface()和getInterfaceDescriptor()
  • BnPmcsServer同时继承IInterfaceIBinder,定义了onTransact(),没有实现
  • PmcsService里具体实现了onTransact()

4. BpBinder客户端

​ 目标:找到一个类,它必须同时拥有IBinder 和 IIterface的特性

client

  • BpRefBase里有IBinder成员变量
  • BpInterface
    • BpInterface继承于BpRefBase,而BpRefBase里有IBinder成员变量,从而获取到IBinder特性
    • BpInterface继承于INTRFACE,这里INTRFACE就是IPmcsService
  • IInterface中函数asBinder()->BpInterface::onAsBinder()->BpInterface::remote(),返回得到mRemote
  • BpPmcsService为客户端,具体向服务端发起请求
  • PmcsProxy为客户端的回调,服务端响应完请求后,调用回调向调用发起者通知执行结果

BpRefbase的mRemote是如何被赋值的?

最后追溯到 IPmcsService.cpp

1
interface_cast<IMediaPlayer>(reply.readStrongBinder()); //reply里读出IBinder,然后转成IMediaPlayer接口对象

通过子类一级一级注入,即new一个BpPmcsService,然后将其转换为父父类IPmcsService

客户端流程

​ 客户端从远端生成一个IBinder对象,再生成BpPmcsService,将其转换为IpmcsService接口对象,调用其接口方法,最终调用到BpBinder的transact()

​ 而客户端的transact()函数通过Binder Driver获取到BBinder对象(IBinder的实现),并调用onTransact()

5. 总流程

pmcs

  • 应用程序的角度
    1. 已知服务名,APP通过getService() 从ServiceManager 获取存储在Parcel对象的服务的信息
    2. APP收到Parcel对象 (通过kernel),获取到服务对应的服务号,mHandle
    3. 以mHandle作为参数输入生成一个IBinder对象(实际是BpBinder)
    4. APP获取到IBinder对象,通过asInterface(IBinder)生成服务对应的Proxy对象(BpPmcsService),将其强转到*IPmcsService,调用接口函数
    5. 所有的接口对象调用最终会走到BpBinder->transact()函数,这个函数调用IPCThreadState->transact()并以Service号作为参数之一
    6. 最终通过系统调用ioctrl() 进入内核空间,Binder驱动根据传进来的Service 号寻找该Service正处于等待状态的Binder Thread, 唤醒它并在该线程内执行相应的函数,并返回结果给APP
-------------本文结束感谢您的阅读-------------
显示 Gitment 评论