Android ParcelFileDescriptor实现进程间通信

需求

一个通信通道,实现跨进程的的Socket网络通信。
具体的通信通道的图如下。

需求分析
  1. 我们需要一个进程一直做通信通道的事情,业务进程把数据通过进程间通信交给通信进程。
  2. 通信进程通过Socket通道将数据发给网络另外一端的通信进程。
  3. 接收端的通信进程把数据再交给业务进程。
android进程间通信基本方式

android进程间通信是使用Binder来传数据,而Binder传输的数据,有一个最为基本的要求,就是要实现Parcelable接口。

ParcelFileDescriptor

ParcelFileDescriptor是android提供的一个数据结构。

文件描述符,是一种程序读写已打开文件、socket的对象。

FileDescriptor对象,它代表了原始的Linux文件描述符
ParcelFileDescriptor对象,是原始文件描述符的一个复制,对象跟fd不同,但都是操作同一个底层文件流以及文件位置指针

public class ParcelFileDescriptor 
extends Object implements Parcelable, Closeable

ParcelFileDescriptor是可以用于进程间Binder通信的FileDescriptor。支持stream 写入和stream 读出

public static class ParcelFileDescriptor.AutoCloseInputStream 
extends FileInputStream public static class ParcelFileDescriptor.AutoCloseOutputStream 
extends FileOutputStream 

我们可以使用

ParcelFileDescriptor open (File file, int mode)

来将PacecelFileDescriptor 与File对应起来,以实现进程间的文件共享。

我们也可以使用

ParcelFileDescriptor[] createPipe ()

来建立一个pipe通信通道,ParcelFileDescriptor数组第一个元素是read端,第二个元素是write端,通过write端的AutoCloseOutputStream和read端的AutoCloseInputStream,我们就可以实现进程见的数据流传输了。

完整的跨进程数据传输方案如下:
  1. 文件传输

    两端业务层都把Uri对应的ParcelFileDescriptor发送给通信层,发送端通信层从AutoCloseInputStream中取数据发送,接收端通信层获取到数据后,写入到AutoCloseOutputStream中。

  2. 流传输

发送端:
1. 业务层调用getOutputStream向通信层发起请求
2. 通信层通过creatPipe 建立一个ParcelFileDescriptor数组,并将write端的pipe[1]返回给业务层
3. 业务层得到pipe[1](ParcelFileDescriptor)后,可以通过AutoCloseOutputStream写入数据
4. 从通信层的pipe[0]的AutoCloseInputStream中读出数据通过socket发送出去

接收端:
1. 业务层调用getInputStream向通信层发起请求
2. 通信层通过creatPipe 建立一个ParcelFileDescriptor数组,并将read端的pipe[0]返回给业务层
3. 业务层得到pipe0后,可以通过AutoCloseInputStream读取数据。(如没有数据,则阻塞,一直等到有数据为止)
4. socket中读取数据,写入到通信层的pipe[1]的AutoCloseOutputStream。(pipe[1]一旦写入,第三步中pipe[2]就可以读取出数据)

简单的ParcelFileDescriptor使用——pipe

public class DemoParcefliledescriptor extends AppCompatActivity {private static final String TAG = "DemoPFD";private static final String[] PERMISSIONS = {Manifest.permission.WRITE_EXTERNAL_STORAGE,};private static final int PERMISSIONS_CODE = 3006;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_demo_null);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {requestPermissions(PERMISSIONS, PERMISSIONS_CODE);}FileOutputStream outputStream = new FileOutputStream(getStreamFd());try {outputStream.write(99);outputStream.write(98);outputStream.close();} catch (IOException e) {e.printStackTrace();}}private FileDescriptor getStreamFd() {ParcelFileDescriptor[] pipes = null;try {pipes = ParcelFileDescriptor.createPipe();new TransferThread(new ParcelFileDescriptor.AutoCloseInputStream(pipes[0])).start();} catch (IOException e) {e.printStackTrace();}return pipes[1].getFileDescriptor();}static class TransferThread extends Thread {InputStream in;FileOutputStream out;TransferThread(InputStream in, FileOutputStream out) {this.in = in;this.out = out;}TransferThread(InputStream in) {this.in = in;File outFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/zlq_pdf");Log.i(TAG, "File: " + outFile.getAbsolutePath());try {out = new FileOutputStream(outFile);} catch (FileNotFoundException e) {e.printStackTrace();}}@Overridepublic void run() {byte[] buf = new byte[1024*2];int len;try {while((len=in.read(buf)) > 0) {out.write(buf, 0, len);Log.i(TAG, "out:" + len);}in.close();out.flush();out.getFD().sync();out.close();} catch (IOException e) {e.printStackTrace();}}}
}


 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对常见FTP客户端/服务器的调查与分析

前言 主要是想看看常见的服务器和客户端是如何实现协议中要求的功能的,。 比如RF959要求的记录结构(Record Structure)、页结构(Page Structure)、Block Mode、Compress Mode,看起来就很抽象。 实测发现…

vue 上传csv文件

index---------主页面(图1) form-----------子页面(图2) index.vue /** 重点!!!! * 获取表单组件传递的信息,传给后端接口 * param {从form表单传递的数据} datas * Fi…

【进阶六】Python实现SDVRPTW常见求解算法——离散粒子群算法(DPSO)

基于python语言,采用经典离散粒子群算法(DPSO)对 带硬时间窗的需求拆分车辆路径规划问题(SDVRPTW) 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整2.1 需求拆分2.2 需求拆分后的服务时长取值问题 3. 求解结果4. …

关于运行阿里云直播Demo报的错

flutter --version dart --version 如何使用Flutter框架推流_音视频终端 SDK(Apsara Video SDK)-阿里云帮助中心MediaBox音视频SDK下载指南_音视频终端 SDK(Apsara Video SDK)-阿里云帮助中心 终端输入 dart pub --trace get --no-precompile 打印详细报错信息 详细咨询…

docker搭建Lazylibrarian

Lazylibrarian 是一个自动化工具,主要用于追踪作者和获取数字阅读材料的元数据。它结合了 Goodreads、LibraryThing 等社交阅读平台的功能,并支持与 Calibre、Calibre-Web 等电子书管理软件的集成,为用户提供了一个全面的电子书管理和阅读解决…

不再写满屏import导入

密密麻麻的import语句不仅仅是一种视觉上的冲击,更是对代码组织结构的一种考验。 我们是如何做到让import“占领满屏“的了,又该如何优雅地管理这些import语句呢? 本文将从产生大量import语句的原因、可能带来的问题以及如何优化和管理impo…

最优算法100例之47-从尾到头打印单链表

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 从尾到头打印单链表 题解报告 方法1:头插法逆置单链表然后依次打印;注意此处是不带头结点的单链表,带头节点的操作稍微有…

Linux 网络排查命令

端口相关服务检查 netstat -ntpl|grep [$Port]说明:[$Port]为相应的端口号。 0.0.0.0代表本机上可用的任意地址。比如,0.0.0.0:80表示本机上所有地址的80端口。 tcp 0.0.0.0:80表示在所有的可用接口上监听TCP的80端口 如果返回结果为空,说明…

Python | Leetcode Python题解之第29题两数相除

题目: 题解: class Solution:def divide(self, dividend: int, divisor: int) -> int:INT_MIN, INT_MAX -2**31, 2**31 - 1# 考虑被除数为最小值的情况if dividend INT_MIN:if divisor 1:return INT_MINif divisor -1:return INT_MAX# 考虑除数为…

ubuntu安装向日葵远程软件

下载链接: https://sunlogin.oray.com/download/linux?typepersonal安装命令:sudo dpkg -i 文件名.deb 启动命令:/usr/local/sunlogin/bin/sunloginclient 卸载命令:sudo dpkg -r sunloginclient 缺少依赖包,先使…

基于Node.js、Spring MVC和Python的WebSocket服务器实现对比

一、引言 随着网络技术的飞速发展,实时通信在现代Web应用中变得越来越重要。WebSocket协议作为一种在单个连接上进行全双工通信的协议,已经成为实现实时Web应用的关键技术之一。WebSocket服务器在这里扮演着重要角色,它能够处理并维持与客户…

Spring ORM

Spring Data JPA 作为Spring Data 中对于关系型数据库支持的一种框架技术,属于 ORM 的一种,通过得当的使用,可以大大简化开发过程中对于数据操作的复杂度。 Java里面写的一段DB操作逻辑,是如何一步步被传递到 DB 中执行了的呢?为什么 Java 里面可以去对接不同产商的 DB 产…

仿真测试平台设计资料:921-6U CPCI卫星接口仿真测试平台

6U CPCI卫星接口仿真测试平台 一、设备概述 卫星接口仿真测试平台基于6U CPCI的结构,包含信号接口前板、后板,计算机主板、机箱、电源等硬件。硬件设计包括:信号接口前板、后板(直接遥测遥控、串行RS422、LVDS,模拟量输…

深入剖析Python中的上下文管理协议及自定义上下文管理器实践

深入剖析Python中的上下文管理协议及自定义上下文管理器实践 引言 在Python编程实践中,上下文管理协议(Context Manager Protocol)是一种强大的工具,它通过简洁优雅的“with”语句帮助我们实现资源获取、使用和释放的自动化管理。这种设计模式大大提高了…

Unity类银河恶魔城学习记录12-13 p135 Merge Skill Tree with Dogge skill源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili​​​​​​​ Inventory.cs using System.Collections.Generic; using Un…

【C++】每日一题 54 螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] #include <iostream> #include <vector>…

基于springboot实现房屋租赁管理系统设计项目【项目源码+论文说明】

基于springboot实现房屋租赁管理系统设计演示 摘要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对房屋租赁信息管理混乱&…

[尚硅谷flink] 检查点笔记

在Flink中&#xff0c;有一套完整的容错机制来保证故障后的恢复&#xff0c;其中最重要的就是检查点。 文章目录 11.1 检查点11.1.1 检查点的保存1&#xff09;周期性的触发保存2&#xff09;保存的时间点3&#xff09;保存的具体流程 11.1.2 从检查点恢复状态11.1.3 检查点算法…

解读宁波TISAX:保障企业安全的关键

&#x1f352;宁波TISAX&#xff0c;❣️作为信息安全领域的&#x1f92d;重要认证体系&#xff0c;为企业&#x1f41e;提供了强大的&#x1f349;安全保障。&#x1f40b;TISAX&#xff0c;&#x1f697;全称为Trusted Information Security Assessment Exchange&#xff0c;…

【树哈希】CF1182D Complete Mirror

CF1182D - Complete Mirror Description 给定一个 n n n 个点的无根树&#xff0c;求一个树根 r o o t root root,使得对于任意两个节点 v 1 , v 2 v_1,v_2 v1​,v2​&#xff0c;若满足 d i s t ( v 1 , r o o t ) d i s t ( v 2 , r o o t ) dist(v_1,root)dist(v_2,ro…