Android学习之路(20) 进程间通信

IPC

IPC为 (Inter-Process Communication) 缩写,称为进程间通信或跨进程通信,指两个进程间进行数据交换的过程。安卓中主要采用 Binder 进行进程间通信,当然也支持其他 IPC 方式,如:管道,Socket,文件共享,信号量等。

Binder简介

1.为什么使用Binder?

性能方面:

在移动设备上(性能受限制的设备,比如要省电),广泛地使用跨进程通信对通信机制的性能有严格的要求,Binder相对于传统的Socket方式,更加高效。Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,共享内存方式一次内存拷贝都不需要,但实现方式又比较复杂。

Binder传输数据的过程:一次拷贝

Socket传输数据的过程:两次拷贝

安全方面:

传统的进程通信方式对于通信双方的身份并没有做出严格的验证,比如 Socket 通信的IP地址是客户端手动填入,很容易进行伪造。然而,Binder机制从协议本身就支持对通信双方做身份校检,从而大大提升了安全性。

2.Binder原理

从进程角度来看IPC(Interprocess Communication)机制

每个Android的进程,只能运行在自己进程所拥有的虚拟地址空间。例如,对应一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间。当然内核空间的大小是可以通过参数配置调整的。对于用户空间,不同进程之间是不能共享的,而内核空间却是可共享的。Client进程向Server进程通信,恰恰是利用进程间可共享的内核内存空间来完成底层通信工作的。Client端与Server端进程往往采用ioctl等方法与内核空间的驱动进行交互。

Binder通信采用C/S架构,从组件视角来说,包含Client、Server、ServiceManager以及Binder驱动,其中ServiceManager用于管理系统中的各种服务。架构图如下所示:

Binder通信的四个角色

  • Client进程:使用服务的进程。
  • Server进程:提供服务的进程。
  • ServiceManager进程:

ServiceManager 的作用是将字符形式的 Binder 名字转化成 Client 中对该 Binder 的引用,使得 Client 能够通过 Binder 名字获得对 Server中Binder 实体的引用。

  • Binder驱动:

​驱动负责进程之间 Binder 通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。

3.Binder间数据传递

进程间数据传递都是需要序列化的。Serializable 和 Parcelable 接口都可以完成序列化,通过 Intent 和 Binder传输数据时候就需要使用 Serializable 和 Parcelable 。

区别和联系:

Serializable 是 Java中提供的接口,序列化和反序列化需要大量的 I/O 操作,开销比较大。而 Parcelable 是安卓中的序列化方式,效率高。Parcelable 主要用在内存序列化上,Serializable 主要用在用于文件,网络中传递。

Binder

Binder 是 Android 中的一个类,实现了 IBinder 接口。

​ 从 IPC 角度来说

Binder 是 Android 中的一种跨进程通信方式,可以理解为一种虚拟的物理设备,它的设备驱动为 /dev/binder。

​ 从 Framework 的角度:

Binder 是 ServiceManager 连接各种 Manager(ActivityManager,WindowManager) 和 ManagerService 的桥梁。

​ 从应用层的角度

Binder 是客户端和服务端进行通信的媒介,当 bindService 时,服务端会返回一个包含了服务端业务调用的 Binder 对象,通过这个 Binder 对象,客户端就可以获取服务端提供的服务或者数据,包括普通服务和 AIDL 服务。

Android中IPC方式

1.使用 Bundle
Bundle 实现了 Parcelable 接口,可以通过 Intent 进行传递。当从一个进程启动另一个进程的 Activity 时,可以在 Bundle 中附加参数,这些数据必须是能够被序列化的。

2.使用文件共享
A进程往文件中写数据,B进程从文件中读数据。在 Windows上,一个文件如果被加了排斥锁将会导致其他线程无法对其进行访问。而 Andorid 是基于 Linux,是的其支持并发 读/写 可以无限制的进行,但是需要注意并发安全问题。

SharedPreferences 是 Android中轻量级的存储方案,通过键值对来存储数据,采用 xml 文件来保存键值对。因为 Android 系统对 读/写 有一定的缓存策略,即在内存中会有一份 SharedPreferences 文件的缓存,在多进程下,系统对它的读写变得不可靠。SharedPreferences 的 get 个 put 方法都是经过 synchronized 修饰的。

3.使用 Messenger
Messenger 也被翻译为信使,通过它可以在不同的进程间传递 Message 对象,在 Message 中放入我们需要传递的数据。它的底层也是常用 AIDL。

服务端通过 Handler 创建一个 Messenger,然后在 Servce 的 onBind 方法中返回这个 Messenger 对象的底层的 Binder即可。客户端通过服务端返回的 IBinder 就可以创建 Messenger来服务端发消息了。

4.使用 AIDL

AIDL 意思即 Android Interface Definition Language,翻译过来就是Android接口定义语言,是用于定义服务器和客户端通信接口的一种描述语言,可以拿来生成用于IPC的代码。从某种意义上说AIDL其实是一个模板,因为在使用过程中,实际起作用的并不是AIDL文件,而是据此而生成的一个IInterface的实例代码,AIDL其实是为了避免我们重复编写代码而出现的一个模板

进程间的通信,速度快(系统底层直接是共享内存),性能稳,效率高,一般进程间通信就用它. AIDL是Binder机制向外提供的接口,目的就是为了方便对Binder的使用.

5.使用 ContentProvider
​ ContentProvider 是 Android 提供的专门用于不同应用间进行数据共享的方式,它的底层实现也是 Binder。

6.使用 Socket
​ Socket 也被称为 “套接字”,分为流式套接字和用户数据报套接字两种,分别对应于网络传输控制层中的 TCP 和 UDP协议。

IPC各种方式比较

Binder连接池

在这种模式下,整个工作机制是这样的;每个业务模块创建自己的AIDL接口并实现此接口,这个时候不同业务模块之间是不能有耦合的,所有实现细节我们要单独开来,然后向服务端提供自己的唯一标识和其对应的Binder对象;对于服务端来说,只需要一个Service就可以了,服务端提供一个queryBinder接口,这个接口能够根据业务模块的特征来返回相应的Binder对象给它们,不同的业务模块拿到所需的Binder对象后就可以进行远程方法调用了。由此可见,Binder连接池的主要作用就是将每个业务模块的Binder请求统一转发到远程Service中去执行,从而避免了重复创建Service的过程,它的工作原理如图所示。

Binder的使用

定义接口

Binder机制通常用于实现进程间的接口调用,我们需要先定义Binder接口。一个典型的Binder接口如下:

public interface IBookManager {public void addBook(Book book);public void deleteBook(int bookId);public Book getBook(int bookId);public List<Book> getBooks();
}

这是一个书管理的Binder接口,包含增加书籍、删除书籍、获取书籍等方法。

实现Binder接口

然后我们需要实现上面的Binder接口,并继承自Binder类,这样这个类的实例就代表了一个Binder实体,可以跨进程传输。

public class BookManager extends Binder implements IBookManager {public void addBook(Book book) { ... }public void deleteBook(int bookId) { ... }public Book getBook(int bookId) { ... }public List<Book> getBooks() { ... }
} 

在Server端注册Binder实体

在提供服务的进程内,我们需要将Binder实体注册到ServiceManager中。这样当其他进程想访问这个Binder实体时,就可以从ServiceManager中获取它。

public class BookManagerService extends Service {private final BookManager bookManager = new BookManager();public void onCreate() {super.onCreate();publishBinderService(CMD_BOOK_MANAGER, bookManager);}
}

在onCreate()方法中我们通过publishBinderService()方法将bookManagerBinder实体发布到ServiceManager中,这样其他进程就可以通过CMD_BOOK_MANAGER这个key来获取这个Binder实体了。

在Client端获取Binder代理并调用

在客户端进程中,我们可以通过ServiceManager访问Server发布的Binder实体。

public void queryBookManager() {// 获取ServiceManager的代理IBinder service = ServiceManager.getService(CMD_BOOK_MANAGER);// 通过服务端返回的IBinder对象生成Binder代理IBookManager bookManager = IBookManager.Stub.asInterface(service);// 通过代理调用服务端的方法List<Book> books = bookManager.getBooks();... 
} 

我们首先通过ServiceManager获取要访问的Binder实体,这个会返回一个IBinder对象。然后通过IBookManager.Stub.asInterface(service)将IBinder对象转成客户端所需的IBookManager接口类型,这个对象就是Binder代理。我们可以通过这个代理对象调用服务端IBookManager接口中的方法。

至此,我们完成了一个跨进程的Binder通信的全过程。客户端通过Binder代理访问服务器提供的服务,服务器通过Binder实体来处理客户端的请求。这整套机制都建立在Binder驱动之上,Binder驱动负责将双方的请求和回复进行传递。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

后端面经学习自测(二)

文章目录 1、Http1.1和2.0的区别大概是什么&#xff1f;HTTP & HTTPS 2、HTTP&#xff0c;用户后续的操作&#xff0c;服务端如何知道属于同一个用户cookie & session & token手机验证码登录流程SSO单点登录 3、如果服务端是一个集群机器&#xff1f;4、hashmap是线…

华为云云耀云服务器L实例评测|基于canal缓存自动更新流程 SpringBoot项目应用案例和源码

前言 最近华为云云耀云服务器L实例上新&#xff0c;也搞了一台来玩&#xff0c;期间遇到各种问题&#xff0c;在解决问题的过程中学到不少和运维相关的知识。 在之前的博客中&#xff0c;介绍过canal的安装和配置&#xff0c;参考博客 拉取创建canal镜像配置相关参数 & …

《Jetpack Compose从入门到实战》第一章 全新的 Android UI 框架

书籍源码 Compose官方文档 《Jetpack Compose从入门到实战》第一章 全新的 Android UI 框架 《Jetpack Compose从入门到实战》 第二章 了解常用UI组件 《Jetpack Compose从入门到实战》第三章 定制 UI 视图 《Jetpack Compose从入门到实战》第八章 Compose页面 导航 《Jet…

【Overload游戏引擎分析】画场景网格的Shader

Overload引擎地址&#xff1a; GitHub - adriengivry/Overload: 3D Game engine with editor 一、栅格绘制基本原理 Overload Editor启动之后&#xff0c;场景视图中有栅格线&#xff0c;这个在很多软件中都有。刚开始我猜测它应该是通过绘制线实现的。阅读代码发现&#xff0…

JAVA面经整理(8)

一)为什么要有区&#xff0c;段&#xff0c;页&#xff1f; 1)页是内存和磁盘之间交互的基本单位内存中的值修改之后刷到磁盘的时候还是以页为单位的索引结构给程序员提供了高效的索引实现方式&#xff0c;不过索引信息以及数据记录都是记录在文件上面的&#xff0c;确切来说是…

矩阵的c++实现(2)

上一次我们了解了矩阵的运算和如何使用矩阵解决斐波那契数列&#xff0c;这一次我们多看看例题&#xff0c;了解什么情况下用矩阵比较合适。 先看例题 1.洛谷P1939 【模板】矩阵加速&#xff08;数列&#xff09; 模板题应该很简单。 补&#xff1a;1<n<10^9 10^9肯定…

给列起别名(关键字:as)

MySQL从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129334507?spm1001.2014.3001.5502 语法格式: select 列名1 as 别名1, 列名2 as 别名2, 列名n as 别名n from 表名; 说明&#xff1a;可以省略as&#xff0c;列名和别名之间使用空格…

MySQL——使用mysqldump备份与恢复数据

目录 1.mysqldump简介 2.mysqldump备份数据 2.1 备份所有数据库 2.2 备份一个/多个数据库 2.3 备份指定库中的指定表 3.mysqldump恢复数据 3.1 恢复数据库 3.2 恢复数据表 1.mysqldump简介 mysqldump命令可以将数据库中指定或所有的库、表导出为SQL脚本。表的结构和表中…

并网逆变器+VSG控制+预同步控制+电流电流双环控制(Simulink仿真实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

火山引擎 ByteHouse:TB 级数据下,如何实现高效、稳定的数据导入

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 近期&#xff0c;火山引擎开发者社区、火山引擎数智平台&#xff08;VeDI&#xff09;联合举办以《数智化转型背景下的火山引擎大数据技术揭秘》为主题的线下 Meeup…

做好微信CRM,这些功能你不可不知!

在当前的数字化时代&#xff0c;微信已成为我们日常生活中的重要元素&#xff0c;无论是社交交流、信息传递还是商务合作&#xff0c;微信都扮演着不可或缺的角色。为了更有效地管理微信资源并提高工作效率&#xff0c;很多组织和公司都选择引入微信CRM系统。那么&#xff0c;怎…

【算法学习】-【双指针】-【盛水最多的容器】

LeetCode原题链接&#xff1a;盛水最多的容器 下面是题目描述&#xff1a; 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。…

sheng的学习笔记-【中文】【吴恩达课后测验】Course 1 - 神经网络和深度学习 - 第三周测验

课程1_第3周_测验题 目录&#xff1a;目录 第一题 1.以下哪一项是正确的&#xff1f; A. 【  】 a [ 2 ] ( 12 ) a^{[2](12)} a[2](12)是第12层&#xff0c;第2个训练数据的激活向量。 B. 【  】X是一个矩阵&#xff0c;其中每个列都是一个训练示例。 C. 【  】 a 4 […

如果在 Mac 上的 Safari 浏览器中无法打开网站

使用网络管理员提供的信息更改代理设置。个人建议DNS解析&#xff0c;设置多个例如114.114.114.114 8.8.8.8 8.8.4.4 如果打不开网站&#xff0c;请尝试这些建议。 在 Mac 上的 Safari 浏览器 App 中&#xff0c;检查页面无法打开时出现的信息。 这可能会建议解决问题的…

pandas read_json时ValueError: Expected object or value的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

坦克世界WOT知识图谱三部曲之爬虫篇

文章目录 关于坦克世界1. 爬虫任务2. 获取坦克列表3. 获取坦克具体信息结束语 关于坦克世界 《坦克世界》(World of Tanks, WOT)是我在本科期间玩过的一款战争网游&#xff0c;由Wargaming公司研发。2010年10月30日在俄罗斯首发&#xff0c;2011年4月12日在北美和欧洲推出&…

IDT 一款自动化挖掘未授权访问漏洞的信息收集工具

IDT v1.0 IDT 意为 Interface detection&#xff08;接口探测) 项目地址: https://github.com/cikeroot/IDT/该工具主要的功能是对批量url或者接口进行存活探测&#xff0c;支持浏览器自动打开指定的url&#xff0c;避免手动重复打开网址。只需输入存在批量的url文件即可。 …

Linux删除空目录/非空目录和文件

一、删除目录 删除名为mydir的空目录: rmdir mydir 删除名为mydir的非空目录(非空目录是指该目录包含了其他文件或子目录&#xff0c;而不是空的或没有任何内容的目录) rm -r mydir 删除mydir1下的空目录mydir2 rmdir mydir1/mydir2 删除当前目录下所有以dir一个数字结尾的目录…

Nginx限流熔断

一、Nginx限流熔断 Nginx 是一款流行的反向代理和负载均衡服务器&#xff0c;也可以用于实现服务熔断和限流。通过使用 Nginx 的限流和熔断模块&#xff0c;比如&#xff1a;ngx_http_limit_req_module 和 ngx_http_limit_conn_module&#xff0c;可以在代理层面对服务进行限流…

set和map的封装

目录 介绍 红黑树代码 set insert的迭代器转换问题 为什么会有这样的问题? 如何解决 代码 map 注意点 代码 介绍 set和map的底层都是红黑树,所以我们可以在自己实现的红黑树(简易版)的基础上,进行封装,成为简易的set和map 红黑树代码 #pragma once#include <…