Android native进程间通信实例-binder结合共享内存
在android源码的驱动目录下,一般会有共享内存的相关实现源码,目录是:kernel\drivers\staging\android\ashmem.c。但是本篇文章不是讲解android共享内存的功能实现原理,而是讲怎么运用它。
1.
在linux中,不同进程间拥有自己独立的内存空间,32位操作系统中好像一个进程能用的内存大小是4G吧。而且一般不同进程间不能够互相使用各自内存的数据。
当然不同进程间共享数据方法很多,比如之前说的进程间通信binder,socket等等,不过android出了一个共享内存的概念,为的是不同进程间能够共同操作同一块内存数据,比如进程1001往一块共享内存addr里面写数据“hello world”,进程1009往这块共享内存addr读取出“hello world”,也能够往这块共享内存addr写数据“hello china”。这就是共同享用了一块内存的基本概念了(说白了就是同耕一块田)。讲的够仔细了吧,如果不清楚评论区见。
注意:好像binder传输的数据实现也是类似于共享内存,读者可以自行去了解。
2.
先说一下等会写程序的思路:
首先想想代码编译出两个可执行文件后如何操作,打开两个终端,都进入设备adb shell,第一个终端执行进程a,第二个终端执行进程b。在进程a输入一串数据后,在进程b中可以读出这段数据(也能够改写这段数据,读者可以自行添加这部分功能)。
然后再想想实现的方式,
进程a:1. 创建共享内存,设置共享内存大小,这时会得到一个fd。2. 获取共享内存地址。3. 先读取地址数据,然后往地址写入数据。4. 把fd通过binder发送给需要使用的进程。
进程b:1. 通过binder读取到fd。2. 用fd获取共享内存地址。3. 读取共享内存数据,然后往地址写入数据。
注意:linux一切皆文件,所以文件描述符fd很重要。
3.
3.1
捋清思路后,就可以开始写代码了(android.mk的编写可以参考之前的文章),进程a,命名为mysharememory_a代码如下:
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <linux/ashmem.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <stddef.h>
#include <linux/ipc.h>
#include <linux/shm.h> #include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <binder/IInterface.h> #define DEVASHMEM "/dev/ashmem"
#define SHNAME "hellomemory"
#define MAXBUFSIZE 1024
#define TRANSFDCODE 1000
#define WRITEDATACODE 1001 using namespace android; int main(int argc, char *argv[])
{
int fd = open(DEVASHMEM, O_RDWR);
if(fd < )
{
return -;
} int ret = ioctl(fd, ASHMEM_SET_NAME, SHNAME);
if(ret < ){
close(fd);
return -;
} char *get_sh_addr_write = NULL;
ret = ioctl(fd, ASHMEM_SET_SIZE, MAXBUFSIZE);
if(ret < ){
close(fd);
return -;
} get_sh_addr_write = (char*)mmap(NULL, MAXBUFSIZE , PROT_READ | PROT_WRITE, MAP_SHARED, fd, );
if(NULL == get_sh_addr_write)
{
return -;
}
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->checkService(String16("mybindertag"));
Parcel data, reply; data.writeDupFileDescriptor(fd);
binder->transact(TRANSFDCODE, data, &reply); char input_data[MAXBUFSIZE] = {};
while()
{
printf("read share memory buf is %s\n", get_sh_addr_write);
printf("please input data to buf :");
scanf("%s", input_data);
getchar(); strcpy(get_sh_addr_write,input_data);
binder->transact(WRITEDATACODE, data, &reply);
}
return ret;
}
3.2
mysharememory_b代码如下:
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <linux/ashmem.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <stddef.h>
#include <linux/ipc.h>
#include <linux/shm.h> #include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <binder/IInterface.h> #define DEVASHMEM "/dev/ashmem"
#define SHNAME "hellomemory"
#define MAXBUFSIZE 1024
#define TRANSFDCODE 1000
#define WRITEDATACODE 1001 using namespace android; int g_sh_fd = ;
class MyBinderService : public BBinder{
status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
int ret;
char *get_sh_addr_read = NULL;
int get_sh_size; printf("songsong!! **** onTransact ***** code = %d \n",code);
switch(code)
{
case TRANSFDCODE:
g_sh_fd = data.readFileDescriptor();
break; case WRITEDATACODE:
get_sh_size = ioctl(g_sh_fd, ASHMEM_GET_SIZE,NULL);
if(get_sh_size > )
{
get_sh_addr_read = (char*)mmap(NULL, get_sh_size, PROT_READ | PROT_WRITE, MAP_SHARED, g_sh_fd, );
}
else
{
printf("mmap failed %d\n", get_sh_size);
return -;
}
printf("what is in the share memory: %s\n", get_sh_addr_read);
break;
default: break;
}
return NO_ERROR;
}
}; int main(int argc, char *argv[])
{
defaultServiceManager()->addService(String16("mybindertag"), new MyBinderService()); sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return ;
}
3.3
回收关闭部分代码可选择添加在mysharememory_b中,如下:
int ret;
ret = munmap((void*)get_sh_addr_read, get_sh_size);
if(ret == -)
{
return -;
} ret = close(g_sh_fd);
if(ret == -)
{
return -;
}
3.4
演示截图:

4. 为了骗取评论,我不再解释代码,心累。不过您可以把代码直接拷贝去编译执行,再通过调试去理解代码的精髓,也是没问题的。
Android native进程间通信实例-binder结合共享内存的更多相关文章
- Android native进程间通信实例-binder篇之——HAL层访问JAVA层的服务
有一天在群里聊天的时候,有人提出一个问题,怎样才能做到HAL层访问JAVA层的接口?刚好我不会,所以做了一点研究. 之前的文章末尾部分说过了service call 可以用来调试系统的binder服务 ...
- Android native进程间通信实例-binder篇之——简单的单工通信
网上找了很多binder相关文章,大部分都是在跟踪binder实现源代码,然后再把框架代码贴出来,看着实在费力. 这篇文章从实际出发,直接用一个案例下手,后续想了解binder相关原理的话,可以参考& ...
- Android native进程间通信实例-binder篇之——用parcel传输数组
和之前稍微不同,这次要稍微分析一下 Parce.cpp 和 android_os_Parcel.cp p的源码,为的是能够掌握调试技巧,后续传输其它类型数据就能举一反三了! 1. 代码共享 这次 ...
- Android native进程间通信实例-binder篇之——解决实际问题inputreader内建类清楚缓存
我在实际开发中,遇到一个问题,在电容屏驱动中没有发送input_sync 给上层,导致电容屏有的数据缓存在inputreader 中,会导致系统一系列奇怪问题发生, 至于为什么驱动不发送input_s ...
- Android native进程间通信实例-socket本地通信篇之——服务端进程异常退出解决办法
导读: 好难受啊,为什么服务端说挂就挂,明明只是客户端关闭而已,服务端怎么能挂呢? 想想,如果手机上使用一个聊天程序的时候,手机端关闭了聊天程序,那么远端服务器程序总不能说挂就挂吧!所以一定要查明真相 ...
- Android native进程间通信实例-socket本地通信篇之——基本通信功能
导读: 网上看了很多篇有关socket本地通信的示例,很多都是调通服务端和客户端通信功能后就没有下文了,不太实用,真正开发中遇到的问题以及程序稳定性部分没有涉及,代码健壮性不够,本系列(socket本 ...
- 【转】Linux环境进程间通信(五) 共享内存(上)
转自:https://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以 ...
- <转>Linux环境进程间通信(五): 共享内存(下)
http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index2.html 系统调用mmap()通过映射一个普通文件实现共享内存.系统V则是通 ...
- <转>Linux环境进程间通信(五): 共享内存(上)
http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写 ...
随机推荐
- 移动IM开发指南2:心跳指令详解
<移动IM开发指南>系列文章将会介绍一个IM APP的方方面面,包括技术选型.登陆优化等.此外,本文作者会结合他在网易云信多年iOS IM SDK开发的经验,深度分析实际开发中的各种常见问 ...
- ZooKeeper学习之路(三)—— Zookeeper常用Shell命令
一.节点增删改查 1.1 启动服务和连接服务 # 启动服务 bin/zkServer.sh start #连接服务 不指定服务地址则默认连接到localhost:2181 zkCli.sh -serv ...
- kubernetes实战篇之helm填坑与基本命令
系列目录 其实前面安装部分我们已经分享一些互联网上其它网友分享的一些坑,本篇介绍helm的基本使用以及在使用过程中碰到的一些坑. 客户端版本和服务端版本不一致问题 有些朋友可能在使用helm init ...
- shell写的俄罗斯方块
共享一下. #!/bin/bash # Tetris Game # xhchen<[email]xhchen@winbond.com.tw[/email]> #APP declaratio ...
- 总结关于CPU的一些基本知识
关于CPU和程序的执行 CPU是计算机的大脑. 程序的运行过程,实际上是程序涉及到的.未涉及到的一大堆的指令的执行过程. 当程序要执行的部分被装载到内存后,CPU要从内存中取出指令,然后指令解码(以便 ...
- (H5)canvas实现裁剪图片和马赛克功能,以及又拍云上传图片
1.核心功能 此组件功能包含: 图片裁剪(裁剪框拖动,裁剪框改变大小): 图片马赛克(绘制马赛克,清除马赛克): 图片预览.图片还原(返回原图.返回处理图): 图片上传(获取签名.上传图片). 2.核 ...
- 寻觅Azure上的Athena和BigQuery (二):神奇的PolyBase
前情回顾 在“数据湖”概念与理论逐渐深入人心的今天,面向云存储的交互式查询这个需求场景显得愈发重要.这是因为原生的云存储(主要指S3这样的对象存储)既能够容纳大容量的明细数据,又能在性能和成本间取得一 ...
- .NetCore应用多个target framework
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFrameworks> ...
- CDQZ集训DAY10 日记
又一次跪了,跪在了神奇的数据范围上. T1上来打完暴力之后觉得是数据结构题,像三维偏序,于是开始往各种数据结构上想,主席树,线段树+calc,平衡树,树套树,CDQ……最终在经过一番思考之后选择去打C ...
- 个人永久性免费-Excel催化剂功能第22波-Excel文件类型、密码批量修改,补齐PowerQuery短板
Excel的多工作薄.多工作表批量合并功能,Excel用户很多这方面的使用场景,也促使了各大Excel各大插件们都在此功能上有所开发,体验程度不一,但总体能够满足大多数的应用场景,本人之前也开发个单独 ...