安卓进程间通信浅谈

Case: /Users/lucas/AndroidStudioProjects/aidldemo-master

一:操作系统

从操作系统原理去看,进程通信主要有三个方法:共享存储、消息传递、管道通信。

二:安卓中的IPC

进程间通信的几种方式:Intent(Bundle),文件共享,Messenger,AIDL,ContentProvider,Socket等。

  • Bundle实现了Parcelable接口
    • 优点:简单易用
    • 缺点:只能传递Bundle支持的数据类型
    • 使用场景:四大组件间的进程通讯
  • 文件共享
    • 优点:简单易用
    • 缺点:不适合高并发的场景,不能做到即使通讯
    • 使用场景:无并发访问的情景,简单的交换数据,实时性要求不高
  • AIDL
    • 优点:功能强大,支持一对多并发通讯,支持实时通信
    • 缺点:一定要处理好线程同步的问题
    • 使用场景:一对多进行通讯,有RPC(远程过程调用协议)的需求
  • Message
    • 优点:功能一般,支持一对多串行通讯,支持实时通信
    • 缺点:不能更好的处理高并发场景,不支持RPC,数据通过Message进行传输,因此只能支持Bundle支持的数据类型
    • 使用场景:低并发的一对多的实时通讯,没有RPC的需求或者说没有返回结果的RPC
  • ContentProvider
    • 优点:主要用于数据访问,支持一对多的并发数据共享
    • 缺点:受约束,主要支队数据源的曾删改查
    • 使用场景:一对多的数据共享
  • Socket(套接字)
    • 优点:功能强大,通过读写网络传输字节流,支持一对多的并打的实时通讯
    • 缺点:不支持直接的RPC
    • 使用场景:万络数据的交换
  • BroadcastReceiver
    • 优点:操作简单,支持一对多实时通信
    • 缺点:只支持数据单向传递,效率低且安全性不高
    • 使用场景:一对多的低频单向通信

Android之所以选择Binder,有2个方面原因

  • 安全,每个进程都会被Android系统分配UID和PID,不想传统的在数据里加入UID,这就让那些恶意进程无法直接和其他进程通信,进程间通信的安全性得到提升
  • 高效,像Socket之类的IPC每次数据拷贝都需要2次,而Binder只需要一次,在手机上这种资源紧张的情况下很重要

2.1 AIDL

AIDLAndroid中实现跨进程通信(Inter-Process Communication)的一种方式。AIDL的传输数据机制基于BinderBinder对传输数据大小有限制, 传输超过1M的文件就会报android.os.TransactionTooLargeException异常(注1),一种解决办法就是使用匿名共享内存进行大文件传输

2.1:共享内存简介

共享内存是进程间通信的一种方式,通过映射一块公共内存到各自的进程空间来达到共享内存的目的。

shmem.png

对于进程间需要传递大量数据的场景下,这种通信方式是十分高效的,但是共享内存并未提供同步机制,一个进程写共享内存时,并无自动机制可以阻止第二个进程开始对它进行读取,所以我们需要类似信号量机制来同步对共享内存的访问。

Android中的匿名共享内存(Ashmem)是基于Linux共享内存的,借助Binder+文件描述符(FileDescriptor)实现了共享内存的传递。它可以让多个进程操作同一块内存区域,并且除了物理内存限制,没有其他大小限制。相对于Linux的共享内存,Ashmem对内存的管理更加精细化,并且添加了互斥锁。Java层在使用时需要用到MemoryFile,它封装了native代码。Android平台上共享内存通常的做法如下:

  • 进程A通过MemoryFile创建共享内存,得到fd(FileDescriptor)
  • 进程A通过fd将数据写入共享内存
  • 进程A将fd封装成实现Parcelable接口的ParcelFileDescriptor对象,通过BinderParcelFileDescriptor对象发送给进程B
  • 进程B获从ParcelFileDescriptor对象中获取fd,从fd中读取数据

2.2:AIDL使用方法

服务端:1.创建接口,2.定义binder,实现接口,3.创建服务,返回binder;

客户端:1.绑定服务,2.实现ServiceConnection绑定监听,3.在绑定成功的回调中,将IBinder转换成AIDL的接口代理对象。

客户端和服务端绑定成功后,就可以通过AIDL的接口代理对象,就像直接调用本地方法一样,调用服务端的方法了。需要注意的是,AIDL间传递的对象要实现Parcelable接口。

2.3:AIDL的回调

原理:和常用的callback接口是一样的,只不过aidl的callback回调是在两个进程内。

服务器:ITaskBinder.Stub() + callback接口

客户端:定义一个calback的具体实现,拿服务端service ,里面register这个callback,然后服务端ITaskBinder.Stub() ->里面callback.xx(),于是调用到客户端定义的callback实现

在aidl文件中,通过oneway修饰,申明方法为异步

2.4:AIDL的底层:binder

两者关系:

AIDL定义的接口,它除了是一个接口以外,它还是一个Binder对象,支持在接口和Binder之间相互转换(asBinder(), asInterface())。创建了AIDL接口后,系统会自动生成其对应的Binder类,它继承了IInterface, 内部有一个静态抽象类Stub和Stub内部的Proxy类。其中Stub继承了Binder类,所以AIDL中的Stub即为一个Binder对象。

binder:

从代码的角度来说,Binder 是 Android 系统源码中的一个类,它实现了 IBinder 接口;

从 IPC 角度来说,Binder 是 Android 中的一种跨进程通信方式;

从 Android Framework 角度来讲,Binder 是 ServiceManager 连接各种 Manager(ActivityManager、WindowManager 等等)和相应 ManagerService 的桥梁;

从 Android 应用层来说,Binder 是客户端和服务端进行通信的媒介,当 bindService 的时候,服务端会返回一个包含了服务端业务调用的 Binder 对象,通过这个 Binder 对象,客户端就可以和服务端进行通信,这里的服务包括普通服务和基于 AIDL 的服务。

AIDL的作用是实现跨进程通讯使用方法也非常的简单,他的设计模式是典型的C/S架构。客户端通过绑定服务端,获取了服务端的IBinder对象,这个IBinder对象,就是代理模式中的那个代理(或者说是c语音中的指针,指向了服务端),然后客户端通过这个代理对象,就可以通过transact方法,向服务端发送数据,实现了进程间的通讯。

2.1 Intent

使用例子:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.putData...  //放一些你需要传递的数据
ComponentName componentName = new ComponentName("com.lucas.test", "com.lucas.test.Main2Activity");//要跳转的包名以及类名
intent.setComponent(componentName);
startActivity(intent);

弊端:Intent 只能传递简单的对象,对象必须实现Pacelable接口序列化。

三:(补充)Binder数据限制

Binder传输数据限制原因:

  • 1.每个进程中会有多个Binder线程,而这些Binder线程又共享创建进程的时候开辟的1M-8K的内存空间,所以在每个Binder线程传输数据的时候,不可能传递1M-8K;
  • 2.另外开辟的这部分内存空间,还会有一些堆栈以及代码块等占用部分内存。

注意

  • 注1:普通的由 Zygote fork 而来的用户进程,所映射的Binder内存大小是不到1M的,准确说是#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))这个限制定义在 frameworks/native/+/4d2f4bb/libs/binder/ProcessState.cpp类中,如果传输数据超过这个大小,系统就会报错,因为Binder本身就是为了进程间频繁而灵活的通信所设计的,并不是为了拷贝大数据而使用的。

参考

一道面试题:使用AIDL实现跨进程传输一个2M大小的文件:https://juejin.cn/post/6990379493235884062

Android intent 传递数据的大小限制:https://blog.csdn.net/u011033906/article/details/117276922

Android 跨进程通信-(十)Binder机制传输数据限制—罪魁祸首Binder线程池:https://blog.csdn.net/nihaomabmt/article/details/116701810

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/41716.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为产品测评官-开发者之声 - ModelArts 真实体验感想

华为产品测评官-开发者之声 - ModelArts 真实体验感想 我先是在6月17日参加了华为在深圳举办的开发者大会,后面看到群里发的"2023华为产品测评官-开发者之声"活动,简单看了一下体验活动的具体事情,感觉好玩…

超声医疗高压功率放大器ATA-4315技术参数

超声波检查或超声诊断,是一种非侵入性的医学检查方法,它利用了声波的高频振动来观察和评估人体内部的器官和组织。它基于不同密度和组织结构中传播的原理。通过将ultrasound(超声波)传递到身体的特定区域,并记录反射回来的声波,我…

flutter开发实战-svga播放svgaplayer_flutter直播礼物特效等效果使用

flutter开发实战-svga播放svgaplayer_flutter直播礼物特效等效果使用 最近开发过程中用到了SVGA进行播放动画,这里记录一下svgaplayer_flutter使用过程。svga可以做一些非常精美的动画,包括直播的刷礼物(火箭、跑车特效动画)等等。 效果图如下 一、SVG…

分区类型ID一键变身!快速改变分区类型ID的简单方法

分区类型ID是什么? 想要改变分区类型ID,先得明白分区类型ID是什么。大多数电脑用户可能只熟悉分区和分区类型,实际上有5种分区类型:主分区、可扩展固件接口(EFI)、扩展分区、逻辑分区和Microsoft保留分…

百分点科技苏萌受邀出席首届全国统计与数据科学联合会议

7月11-13日,首届全国统计与数据科学联合会议在北京举行,会议由中国现场统计研究会、中国数学会概率统计分 会、全国工业统计学教学研究会和中国商业统计学会联合主办,北京大学统计科学中心承办,旨在促进统计与数据科学领域发展&a…

vuecli5.x 配置图片输出为base64

解释:webpack的默认配置是小于一定的文件大小就要将图片转为base64, 所以尽量将这个阈值调大你的图片就可以转为base64; 当然这种做法不好, 会导致代码文件变大, 不过为了满足需求也没得办法。这年头大家都用 vite 了, 网上没有 vuecli5.x 这方面的记录, 写篇文章记…

Java经典面试解析:服务器卡顿、CPU飙升、接口负载剧增

01 线上服务器CPU飙升,如何定位到Java代码 解决这个问题的关键是要找到Java代码的位置。下面分享一下排查思路,以CentOS为例,总结为4步。 第1步,使用top命令找到占用CPU高的进程。 第2步,使用ps –mp命令找到进程下…

Flink 在新能源场站运维的应用

摘要:本文整理自中南电力设计院工程师、注册测绘师姚远,在 Flink Forward Asia 2022 行业案例专场的分享。本篇内容主要分为四个部分: 建设背景 技术架构 应用落地 后续及其他 点击查看原文视频 & 演讲PPT 一、建设背景 建设背景主要…

农产品后台管理系统(一)——项目总览

后端技术栈 SpringBoot2.xMybatis-plusMysql8.0redisjsoup(测试爬取数据) 前端技术栈 Vue3EchartsAxios前端组件:element-china-area-data、element-plus 项目概览截图 登录界面 注册界面 农产品发布界面 用户管理界面 用户画像界面 订单…

centos 安装pyzbar

需求: 运行程序报错 ImportError: Unable to find zbar shared library 进程: 直接使用yum 安装 yum install python-devel && yum install zbar-devel 有时候会能成功,大多数时候python-devel 能成功但是 zbar-devel 会失败 下载…

国密算法概述、及算法的集成应用(sm2、sm3、sm4)

国密算法概述、及算法的集成应用(sm2、sm3、sm4) 一、概述二、分类概述3.1、SM1对称密码3.2、SM2椭圆曲线公钥密码算法3.3、SM3杂凑算法3.4、SM4对称算法3.5、SM7对称密码3.6、SM9标识密码算法3.7、ZUC祖冲之算法 三、集成SM2加解密四、集成SM3加密、验签…

vue3和gin框架实现简单的断点续传

vue3和gin框架实现简单的断点续传 前端代码 Test.vue <template><div><inputtype"file"ref"uploadRef"change"upload"multiple/><templatev-for"item in fileList":key"item.key"><br><…

Grafana_数据可视化工具

目录 一、简介 二、安装部署 1、下载 2、安装 3、启用 三、使用简介 1、添加数据源 2、创建DashBoard 3、查看dashboard 4、选择查看的时间段 5、阈值颜色控制 源码等资料获取方法 一、简介 Grafana是一个跨平台开源的纯html/js编写的度量分析和可视化工具&#x…

如何应用MySQL高阶语句(子查询)

目录 一、SQL高阶语句 常用查询 关键字排序 升序降序 按区域进行查找 分组统计 limit限制显示结果条目 As别名设置 使用场景 嵌套克隆复制表结构 二、通配符 三、子查询 insert子查询 update子查询 delete子查询 Exists检测 一、SQL高阶语句 常用查询 对于MyS…

飞行动力学 - 第11节-纵向静稳定性及各部件贡献 之 基础点摘要

飞行动力学 - 第11节-纵向静稳定性及各部件贡献 之 基础点摘要 1. 气流角2. 操纵面偏角3. 系数的符号4. 纵向、横向、航向稳定性5. 纵向静稳定性5.1 定义5.2 准则5.3 举例5.4 假设5.5 分析5.5.1 机身贡献5.5.2 机翼贡献5.5.3 尾翼贡献 6. 参考资料 1. 气流角 迎角&#xff1a;…

成功解决wget下载报错 : wget HTTP request sent, awaiting response... 403 Forbidden

成功解决wget下载报错 : wget HTTP request sent, awaiting response... 403 Forbidden 问题描述解决方案原理什么是User Agent解决 问题描述 –2023-07-15 02:32:57-- https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2023.03-Linux-x86_64.sh Resolving mi…

7月31日起,这类产品将禁止在亚马逊美国站销售!

亚马逊美国站发布公告称由于口腔胶带&#xff08;睡眠胶带&#xff09;在睡觉时存在潜在危险&#xff0c;出于对消费者的安全考虑&#xff0c;任何睡眠胶带产品的listing将在亚马逊商店下架&#xff0c;以下是公告内容&#xff1a; 自2023年7月31日起&#xff0c;口腔胶带&…

uni-app做h5IOS底部tabbar高度在不同的tabbar页面会忽高忽低

原因不祥&#xff0c;解决办法的话在App.vue中 <style langscss> //每个页面公共css page { height:100vh; } </style>

什么是云应用程序?

应用程序优先的云服务的日益普及导致应用程序与云服务的融合程度比以前更深。应用程序和云之间的运行时边界正在从虚拟机转移到容器和函数。集成边界正在从仅访问数据库和消息代理转向应用程序的机械部分混合并在云中运行的边界。在这个最终架构中&#xff0c;应用程序是“云绑…

二、DDL-1.数据库操作

一、查询 1、查询所有数据库 show databases; MySQL自带的默认的数据库有四个&#xff1a; 二、创建 1、创建一个新的数据库itcast&#xff08;不区分大小写&#xff09;&#xff1a; create database itcast; 查询所有数据库&#xff1a;多了itcast 2、再创建同名的数据库…