文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

跟着小白一起学鸿蒙# Binder机制剖析和使用

2024-11-30 17:14

关注

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

原理

1. 物理内存中开辟4096字节内存(1m-8k)
2. 物理内存与磁盘内存对应
3. mmu将mmap开辟的物理内存地址转换成虚拟地址

Binder概述

OpenBinder is a system for inter-process communication. It was developed at Be Inc. and then Palm, Inc. and was the basis for the Binder framework now used in the Android operating system developed by Google.

OpenBinder allows processes to present interfaces which may be called by other threads. Each process maintains a thread pool which may be used to service such requests. OpenBinder takes care of reference counting, recursion back into the original thread, and the inter-process communication itself. On the Linux version of OpenBinder, the communication is achieved using ioctls on a given file descriptor, communicating with a kernel driver.

The kernel-side component of the Linux version of OpenBinder was merged into the Linux kernel mainline in kernel version 3.19, which was released on February 8, 2015.

Binder是解决进程间通讯问题的框架

  1. 驱动:kernel/linux/linux-xxx/drivers/android/binderXXX
  2. 服务:foundation/communication/ipc
  3. 框架:各种NAPI里面和对应的服务接口:如foundation/communication/xxx/frameworks/js/napi/xxx和foundation/communication/xxx/services/bluetooth/service/xxx

在OpenHarmony上表现的功能是:

  1. 提供客户端-服务器(Client-Server)模型,服务请求方(Client)可获取提供服务提供方(Server)的代理 (Proxy),并通过此代理读写数据来实现进程间的数据通信。通常,系统能力(System Ability)Server侧会先注册到系统能力管理者(System Ability Manager,缩写SAMgr)中,SAMgr负责管理这些SA并向Client提供相关的接口。Client要和某个具体的SA通信,必须先从SAMgr中获取该SA的代理,然后使用代理和SA通信。三方应用可以使用FA提供的接口绑定服务提供方的Ability,获取代理,进行通信。

在OpenHarmony里的限制是:

  1. 单个设备上跨进程通信时,传输的数据量最大约为1MB,过大的数据量请使用匿名共享内存。
  2. 不支持把跨设备的Proxy对象传递回该Proxy对象所指向的Stub对象所在的设备。
  1. 用户空间运行:Client,Service和Service Manager;内核空间运行:Binder Driver
  2. Client,Server和Service Manager通过系统调用open,mmap和ioctl来访问设备文件/dev/binder。从而实现进程间通信
  3. 功能详细如下:
#define BINDER_WRITE_READ   _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, __s32)
#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32)
#define BINDER_THREAD_EXIT _IOW('b', 8, __s32)
#define BINDER_VERSION _IOWR('b', 9, struct binder_version)
#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
#define BINDER_FEATURE_SET _IOWR('b', 30, struct binder_feature_set)
#define BINDER_GET_ACCESS_TOKEN _IOWR('b', 31, struct access_token)
  1. 对应文件如下
.
├── binder_alloc.c
├── binder_alloc.h
├── binder_alloc_selftest.c
├── binder.c
├── binder_trace.h
├── Kconfig
└── Makefile
  1. Binder通信过程介绍
  1. Service使用 BINDER_SET_CONTEXT_MGR命令通过Ioctl将自己注册成为ServiceMannager
  2. Client向Binder驱动发起获取服务的请求,Binder驱动通过Client需要获取服务的名称,从ServiceManager中获取对Binder实体的引用,通过获得到的引用就能实现和Server进程的通信
  1. IPC通信过程介绍
  1. 首先Binder驱动在内核空间创建一个数据接收缓存区
  2. 接着在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系
  3. Client通过系统调用copy_from_user()将数据拷贝到内核中的内核缓存区,由于内核缓存区和Service的用户空间存在内存映射,所以Service进程的用户空间也有了此数据,这就完成一次跨进程通信

角色说明

  1. Client进程:使用服务的进程
  2. Server进程:提供服务的进程
  3. Service Manager进程:管理Service注册与查询(将字符形式的Binder名字转化成Client中对该Binder的引用)
  4. Binder驱动:虚拟设备驱动,是连接Service进程,Client进程和Service Manager的桥梁,具体作用为:1.传递进程间的数据,通过内存映射。2.实现线程控制:采用Binder的线程池,并由Binder驱动自身进行管理。
import rpc from "@ohos.rpc"
import featureAbility from "@ohos.ability.featureAbility"

Native侧编译依赖

sdk依赖:

external_deps = [
"ipc:ipc_core",
]

此外, IPC/RPC依赖的refbase实现在公共基础库下,请增加对utils的依赖:

external_deps = [
"c_utils:utils",
]

JS侧实现跨进程通信基本步骤:

  1. 获取代理

    使用ohos.ability.featureAbility提供的connectAbility方法绑定Ability,在参数里指定要绑定的Ability所在应用的包名、组件名,如果是跨设备的情况,还需要指定所在设备的NetworkId。用户需要在服务端的onConnect方法里返回一个继承自ohos.rpc.RemoteObject的对象,此对象会在其onRemoteMessageRequest方法里接收到请求。

  2. 发送请求

    客户端在connectAbility参数指定的回调函数接收到代理对象后,使用ohos.rpc模块提供的方法完成RPC通信,其中MessageParcel提供了读写各种类型数据的方法,IRemoteObject提供了发送请求的方法,RemoteObject提供了处理请求的方法onRemoteRequest,用户需要重写。

Native侧实现跨进程通信的基本步骤:

  1. 定义接口类

    接口类继承IRemoteBroker,定义描述符、业务函数和消息码。

  2. 实现服务提供端(Stub)

    Stub继承IRemoteStub(Native),除了接口类中未实现方法外,还需要实现AsObject方法及OnRemoteRequest方法。

  3. 实现服务请求端(Proxy)

    Proxy继承IRemoteProxy(Native),封装业务函数,调用SendRequest将请求发送到Stub。

  4. 注册SA

    服务提供方所在进程启动后,申请SA的唯一标识,将Stub注册到SAMgr。

  5. 通过SA的标识和设备NetworkId,从SAMgr获取Proxy,通过Proxy实现与Stub的跨进程通信。

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

来源:51CTO 开源基础软件社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯