Android 如何实现高效跨进程传递大数据

  • A+
所属分类:Android源码分析

第一.可以实现进程间通信的方式

1.管道,一对一通信,两次拷贝,不满足一对多和效率方面要求

2.socket通信,一对多,性能太低,而且不安全

3.共享内存,多对多,0拷贝,效率高,但是不安全

4.binder,一对多,一次拷贝,效率高,实名安全

第二.安卓系统中都用到了哪些进程间通信方式(应该是都用了)

1.socket通信,SystemService进程和Zygote进程的通信方式就是scoket,那是因为Zygote进程是先创建的进程,是SystemService进程的父进程,因此只能作为服务端,而SystemService作为客户端,SystemService中才会去启动binder驱动,因此无法实现于Zygote进程的通信,因此借助于socket实现通信。

2.共享内存,安卓系统之间传递大文件大数据时用

3.binder,应用之间传递数据时基本上都用这个方法

第三. binder进程间通信的问题

binder实现进程间通信,大小是有限制的,大小限制为1M-8K的大小,为什么是1m-8k呢,因为mmap函数的基本单位为页,而每页的大小为4K,也就是说有2页的数据是额外的数据,额外的数据是什么呢?参考一下http通信协议,http由请求行、请求头、请求体三部分组成,同样的道理,其实binder进行进程间通信也需要这些信息,因此留出来来8K的内存大小来传递请求头和请求行等信息,这8K的内容为系统自动配置的,我们无法使用这8K内存大小。具体到底层代码,底层copy_from_user方法,被调用了2次,第一次传递的数据大小为8K,第二次传递的数据大小为我们传递的真实数据内容,大小为1M-8k.

第四.如何高效传递大文件

1.方法一:使用binder机制

  上面分析了,binder机制最大的传输数据量大小为1M-8K,那如何传递大于1M-8k的内容呢?答案是分段传输。我们可以把文件分割为多端,分段传输,然后再进行合并。(服务端向客户端传递大文件,反向思路一样)总体思路为:

1)客户端与服务端建立连接

2)服务端先告诉客户端数据量总大小,客户端建立同样大小容器等待接收

3)服务端将数据分割,分段传输给客户端,客户端分段接收,拼接到结果容器中

4)服务端告知客户端数据传输结束,客户端进行数据还原展示

特点:分段传输(参考网络通信下载文件思路),效率高,测试发现比方法二还要高

2.采用共享内存+binder方式

由于是跨进程大文件传递文件,共享内存的0拷贝肯定是最合适的,但是共享内存需要借助binder来将文件描述符发送给客户端,客户端通过文件描述符拿到数据。思路如下:

1)服务端开启共享内存,将数据存入共享内存区域

2)通过binder将文件描述符发送到客户端

3)客户端通过文件描述符拿到共享内存数据

特点:效率高,但是亲测发现其实和binder分段传输效率差不多。

demo下载地址: 安卓跨进程高效通信demo-Android文档类资源-CSDN下载

w3cjava

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: