当前位置: 首页 > news >正文

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驱动负责将双方的请求和回复进行传递。

相关文章:

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

IPC IPC为 (Inter-Process Communication) 缩写&#xff0c;称为进程间通信或跨进程通信&#xff0c;指两个进程间进行数据交换的过程。安卓中主要采用 Binder 进行进程间通信&#xff0c;当然也支持其他 IPC 方式&#xff0c;如&#xff1a;管道&#xff0c;Socket&#xff0…...

机器学习——KNN算法流程详解(以iris为例)

、 目 录 前情说明 问题陈述 数据说明 KNN算法流程概述 代码实现 运行结果 基于可视化的改进 可视化代码 全部数据可视化总览 分类投票结果 改进后最终代码 前情说明 本书基于《特征工程入门与入门与实践》庄家盛 译版P53页K最近邻&#xff08;KNN&#xff09;算…...

国庆假期day5

作业&#xff1a;请写出七层模型及每一层的功能&#xff0c;请绘制三次握手四次挥手的流程图 1.OSI七层模型&#xff1a; 应用层--------提供函 表示层--------表密缩 会话层--------会话 传输层--------进程的接收和发送 网络层--------寻主机 数据链路层----相邻节点的可靠传…...

ES6中的let、const

let ES6中新增了let命令&#xff0c;用来声明变量&#xff0c;和var类似但是也有一定的区别 1. 块级作用域 只能在当前作用域内使用&#xff0c;各个作用域不能互相使用&#xff0c;否则会报错。 {let a 1;var b 1; } console.log(a); // 会报错 console.log(b); // 1为什…...

Python 列表操作指南3

示例&#xff0c;将新列表中的所有值设置为 ‘hello’&#xff1a; newlist [hello for x in fruits]表达式还可以包含条件&#xff0c;不像筛选器那样&#xff0c;而是作为操纵结果的一种方式&#xff1a; 示例&#xff0c;返回 “orange” 而不是 “banana”&#xff1a; …...

三个要点,掌握Spring Boot单元测试

单元测试是软件开发中不可或缺的重要环节&#xff0c;它用于验证软件中最小可测试单元的准确性。结合运用Spring Boot、JUnit、Mockito和分层架构&#xff0c;开发人员可以更便捷地编写可靠、可测试且高质量的单元测试代码&#xff0c;确保软件的正确性和质量。 一、介绍 本文…...

【nginx】Nginx配置:

文章目录 一、什么是Nginx&#xff1a;二、为什么使用Nginx&#xff1a;三、如何处理请求&#xff1a;四、什么是正向代理和反向代理&#xff1a;五、nginx 启动和关闭&#xff1a;六、目录结构&#xff1a;七、配置文件nginx.conf&#xff1a;八、location&#xff1a;九、单页…...

CSS3与HTML5

box-sizing content-box&#xff1a;默认&#xff0c;宽高包不含边框和内边距 border-box&#xff1a;也叫怪异盒子&#xff0c;宽高包含边框和内边距 动画&#xff1a;移动translate&#xff0c;旋转、transform等等 走马灯&#xff1a;利用动画实现animation&#xff1a;from…...

redis的简单使用

文章目录 环境安装与配置redis发布-订阅相关命令redis发布-订阅的客户端编程redis的订阅发布的例子 环境安装与配置 sudo apt-get install redis-server # ubuntu命令安装redis服务ubuntu通过上面命令安装完redis&#xff0c;会自动启动redis服务&#xff0c;通过ps命令确认&a…...

Windows下启动freeRDP并自适应远端桌面大小

几个二进制文件 xfreerdp # Linux下的&#xff0c;an X11 Remote Desktop Protocol (RDP) client which is part of the FreeRDP project wfreerdp.exe # Windows下的&#xff0c;freerdp2.0 主程序&#xff0c;freerdp3.0将废弃 sdl-freerdp.exe # Windows下的&…...

ES6中的数值扩展

1. 二进制和八进制的表示法 二进制和八进制的前缀分别为0b(或0B)和0o(或0O)表示 在ES5的严格模式下&#xff0c;八进制不再允许使用前缀0表示 如果要将0b和0x前缀的字符串数值转为十进制&#xff0c;要使用Number方法 Number(0b111); // 7 Number(0o10); // 82. Number.isF…...

自定义注解实现Redis分布式锁、手动控制事务和根据异常名字或内容限流的三合一的功能

自定义注解实现Redis分布式锁、手动控制事务和根据异常名字或内容限流的三合一的功能 文章目录 [toc] 1.依赖2.Redisson配置2.1单机模式配置2.2主从模式2.3集群模式2.4哨兵模式 3.实现3.1 RedisConfig3.2 自定义注解IdempotentManualCtrlTransLimiterAnno3.3自定义切面Idempote…...

Linux:minishell

目录 1.实现逻辑 2.代码及效果展示 1.打印字符串提示用户输入指令 2.父进程拆解指令 3.子进程执行指令,父进程等待结果 4.效果 3.实现过程中遇到的问题 1.打印字符串的时候不显示 2.多换了一行 3.cd路径无效 4.优化 1.ll指令 2.给文件或目录加上颜色 代码链接 模…...

STM32驱动步进电机

前言 &#xff08;1&#xff09;本章介绍用stm32驱动42步进电机&#xff0c;将介绍需要准备的硬件器材、所需芯片资源以及怎么编程及源代码等等。 &#xff08;2&#xff09;实验效果&#xff1a;按下按键&#xff0c;步进电机顺时针或逆时针旋转90度。 &#xff08;3&#xff…...

计算机视觉——飞桨深度学习实战-深度学习网络模型

深度学习网络模型的整体架构主要数据集、模型组网以及学习优化过程三部分&#xff0c;本章主要围绕着深度学习网络模型的算法架构、常见模型展开了详细介绍&#xff0c;从经典的深度学习网络模型以CNN、RNN为代表&#xff0c;到为了解决显存不足、实时性不够等问题的轻量化网络…...

用c动态数组(不用c++vector)实现手撸神经网咯230901

用c语言动态数组(不用c++的vector)实现:输入数据inputs = { {1, 1}, {0,0},{1, 0},{0,1} };目标数据targets={0,0,1,1}; 测试数据 inputs22 = { {1, 0}, {1,1},{0,1} }; 构建神经网络,例如:NeuralNetwork nn({ 2, 4,3,1 }); 则网络有四层、输入层2个nodes、输出层1个节点、第…...

视频讲解|基于DistFlow潮流的配电网故障重构代码

目录 1 主要内容 2 视频链接 1 主要内容 该视频为基于DistFlow潮流的配电网故障重构代码讲解内容&#xff0c;对应的资源下载链接为基于DistFlow潮流的配电网故障重构(输入任意线路)&#xff0c;对该程序进行了详尽的讲解&#xff0c;基本做到句句分析和讲解&#xff08;讲解…...

Ultralytics(YoloV8)开发环境配置,训练,模型转换,部署全流程测试记录

关键词&#xff1a;windows docker tensorRT Ultralytics YoloV8 配置开发环境的方法&#xff1a; 1.Windows的虚拟机上配置&#xff1a; Python3.10 使用Ultralytics 可以得到pt onnx&#xff0c;但无法转为engine&#xff0c;找不到GPU&#xff0c;手动转也不行&#xff0…...

springboot之@ImportResource:导入Spring配置文件~

ImportResource的作用是允许在Spring配置文件中导入其他的配置文件。通过使用ImportResource注解&#xff0c;可以将其他配置文件中定义的Bean定义导入到当前的配置文件中&#xff0c;从而实现配置文件的模块化和复用。这样可以方便地将不同的配置文件进行组合&#xff0c;提高…...

阿里云服务器免费申请入口_注册阿里云免费领4台服务器

注册阿里云账号&#xff0c;免费领云服务器&#xff0c;最高领取4台云服务器&#xff0c;每月750小时&#xff0c;3个月免费试用时长&#xff0c;可快速搭建网站/小程序&#xff0c;部署开发环境&#xff0c;开发多种企业应用。阿里云百科分享阿里云服务器免费领取入口、免费云…...

ES6中的async、await函数

async是为了解决异步操作&#xff0c;其实是一个语法糖&#xff0c;使代码书写更加简洁。 1. async介绍 async放在一个函数的前面&#xff0c;await则放在异步操作前面。async代表这个函数中有异步操作需要等待结果&#xff0c;在一个async函数中可以存在多个await&#xff0…...

代码随想录算法训练营第五十六天 | 动态规划 part 14 | 1143.最长公共子序列、1035.不相交的线、53. 最大子序和(dp)

目录 1143.最长公共子序列思路代码 1035.不相交的线思路代码 53. 最大子序和&#xff08;dp&#xff09;思路代码 1143.最长公共子序列 Leetcode 思路 本题和718. 最长重复子数组 区别在于这里不要求是连续的了&#xff0c;但要有相对顺序&#xff0c;即&#xff1a;“ace” …...

【数据挖掘】2021年 Quiz 1-3 整理 带答案

目录 Quiz 1Quiz 2Quiz 3Quiz 1 Problem 1 (30%). Consider the training data shown below. Here, A A A and B B B</...

【软件设计师-中级——刷题记录6(纯干货)】

目录 管道——过滤器软件体系结构风格优点&#xff1a;计算机英语重点词汇&#xff1a;单元测试主要检查模块的以下5个特征&#xff1a;数据库之并发控制中的事务&#xff1a;并发产生的问题解决方案:封锁协议原型化开发方法&#xff1a; 每日一言&#xff1a;持续更新中... 个…...

微信小程序点单左右联动的效果实现

微信小程序点单左右联动的效果实现 原理解析&#xff1a;   点击左边标签会跳到右边相应位置&#xff1a;点击改变rightCur值&#xff0c;转跳相应位置滑动右边&#xff0c;左边标签会跳到相应的位置&#xff1a;监听并且设置每个右边元素的top和bottom&#xff0c;再判断当…...

Socket通信

优质博文IT-BLOG-CN 一、简介 Socket套接字&#xff1a;描述了计算机的IP地址和端口&#xff0c;运行在计算机中的程序之间采用socket进行数据通信。通信的两端都有socket&#xff0c;它是一个通道&#xff0c;数据在两个socket之间进行传输。socket把复杂的TCP/IP协议族隐藏在…...

TCP 如何保证有效传输及拥塞控制

TCP&#xff08;传输控制协议&#xff09;可以通过以下机制保证有效传输和拥塞控制&#xff1a; 确认机制&#xff1a;TCP使用确认机制来保证数据的有效传输。发送方在发送数据的同时还会发送一个确认请求&#xff0c;接收方收到数据后会回复确认响应。如果发送方没有收到确认响…...

PyQt5+Qt设计师初探

在上一篇文章中我们搭建好了PyQt5的开发环境&#xff0c;打铁到趁热我们基于搭建好的环境来简单实战一把 一&#xff1a;PyQt5包模块简介 PyQt5包括的主要模块如下。 QtCore模块——涵盖了包的核心的非GUI功能&#xff0c;此模块被用于处理程序中涉及的时间、文件、目录、数…...

rust cargo

一、cargo是什么 Cargo是Rust的构建工具和包管理器。 Cargo除了创建工程、构建工程、运行工程等功能&#xff0c;还具有下载依赖库、编译依赖等功能。 真正编写程序时&#xff0c;我们不直接用rustc&#xff0c;而是用cargo。 二、使用cargo &#xff08;一&#xff09;使用…...

CANoe.Diva生成测试用例

Diva目录 一、CANoe.Diva打开CDD文件二、导入CDD文件三、ECU Information四、时间参数设置五、选择是否测试功能寻址六、勾选需要测试服务项七、生成测试用例 一、CANoe.Diva打开CDD文件 CANoe.Diva可以通过导入cdd或odx文件&#xff0c;自动生成全面的测试用例。再在CANoe中导…...

公司网站二维码怎么做的/百度seo怎么收费

Cocos2d-x 3.0新引擎目录结构2014年4月29日 Cocos2d-x 3.0学习作为一个Cocos2d-x的菜鸟&#xff0c;我倒是挺愿意关注不同版本之间的区别&#xff0c;Cocos2d-x 3.0自2013年7月份开始发布alpha0-pre版本&#xff0c;到2014年4月23日发布正式版&#xff0c;历经9个版本&#xf…...

网站建设分析报告/搜一搜

note:本文短代码实现环境&#xff1a;win10,python3 本文代码执行情况 python打开浏览器方法一&#xff1a; 通过引用os包&#xff0c;调用system方法调用系统的ie程序来打开网址 代码如下&#xff1a; import os os.system("C:/Program Files/Internet Explorer/iexplore…...

web开发是做网站/宁德市人社局官网

说明本文假定读者已具备基本的C编译知识。如非特殊说明&#xff0c;文中“源文件”指 * .c文件&#xff0c;“头文件”指 *.h文件&#xff0c;“引用”指包含头文件。一、头文件作用C语言里&#xff0c;每个源文件是一个模块&#xff0c;头文件为使用该模块的用户提供接口。接口…...

外贸先做网站再开公司/如何注册域名及网站

a [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]目前通过a可以获取如下格式&#xff1a;[0,1,2,3][0,1,2,3][0,1,2,3][0,1,2,3]现在想要通过a得到如下格式&#xff1a;[0,0,0,0][1,1,1,1][2,2,2,2][3,3,3,3]如何实现上面的要求&#xff1f;转载于:https://blog.5…...

拼多多网站开发/苏州网络推广服务

2019独角兽企业重金招聘Python工程师标准>>> 米泽牛肉便当 牛肉どまん中 图/iwa-chan.at.webry.info 说到日本铁路便当&#xff0c;第一个肯定得介绍山形县米泽站的特色便当——米泽牛肉便当。自1992年推出后&#xff0c;就稳居日本超人气铁路便当名单&#xff0c;可…...

电商网站开发主要技术问题/关于友情链接说法正确的是

当我们想要对应用程序的请求或响应进行一些预处理/后处理时&#xff0c;使用截取过滤器设计模式。 在将请求传递到实际目标应用程序之前&#xff0c;在请求上定义和应用过滤器。 过滤器可以进行请求的认证/授权/日志记录或跟踪&#xff0c;然后将请求传递给相应的处理程序。 以…...