【Android】の基础——IPC(进程间通信)

来源:互联网 发布:乐视手机清空数据开机 编辑:程序博客网 时间:2024/06/14 23:04

  • 各种方式比较
    • Bundle
        • 通过Bundle的优点
        • 通过Bundle的缺点
    • 文件
        • 通过文件的优点
        • 缺点文件的缺点
    • Socket
        • 使用Socket的优点
        • 使用Socket的缺点
    • AIDL
        • 使用AIDL优点
        • 使用AIDL缺点
    • Messager
        • 使用Messager优点
        • 使用Messager缺点
    • ContentProvider
        • 使用ContentProvider优点
        • 使用ContentProvider缺点
    • Binder连接池
        • 使用BinderPool的优点
        • 使用BinderPool的优点
  • 几种方式的流程
    • Messager流程
    • AIDL流程
  • Binder
    • Binder的工作原理
      • ServiceManager
      • 为什么说Binder只进行一次拷贝
  • 匿名共享内存

Android实现IPC主要有这几种方式:
1. 使用bundle
2. 使用文件
3. 使用Socket
4. 使用AIDL
5. 使用Messager
6. 使用ContentProvider
7. 使用Binder连接池

各种方式比较

Bundle

Bundle:在Bundle中附加数据并通过Intent传输

通过Bundle的优点

简单易用。主要用于四大组件。

通过Bundle的缺点

只能传输Bundle支持的类型。(简单数据类型和序列化类型http://blog.csdn.net/a565815942/article/details/78065395#java的serializable和安卓parcelable)

文件

文件:两个进程通过读写同一个文件来交换数据。

通过文件的优点

简单易用。适用于单线程读写,如果多线程需要同步。

缺点文件的缺点

不适合高并发,不能即时通讯。

Socket

Socket:使用TCP和UDP协议进行网络通信

使用Socket的优点

可以通过网络传输字节流,支持一对多。

使用Socket的缺点

实现细节繁琐。

AIDL

AIDL:Android Interface Definition Language

使用AIDL优点

功能强大,支持一对多并发,支持实时通讯。

使用AIDL缺点

使用复杂。

Messager

Messager:基于消息的进程间通信

使用Messager优点

支持一对多串行通信,支持试试通信。

使用Messager缺点

不能很好的处理高并发,因为通过Message所以只能传输Bundle。

ContentProvider

ContentProvider:专门用于不同应用间的数据共享

使用ContentProvider优点

在数据源访问方面功能强大,支持多对一并发。

使用ContentProvider缺点

使受约束的AIDL,主要提供增删改查。

Binder连接池

使用BinderPool的优点:

避免多次创建Service。

使用BinderPool的优点:

适用稍复杂,需要实现BinderPool的AIDL接口。

几种方式的流程

Messager流程

  1. 端:创建一个Service、Handler、Messager,在onBind()方法返回Messager底层的Binder。
  2. 客户端:绑定Service,获取到IBinder并创建Messager,通过它向服务端发送消息。
  3. 客户端可以创建一个Handler并创建一个新的Messager,通过Message的eplyTo参数传递给服务端。

AIDL流程

  1. 服务端:创建一个Service,创建一个AIDL文件在其中声明接口,并在Service中实现接口。
  2. 客户端:绑定Service获取Binder转化为AIDL接口所属类型,并调用其方法。

Binder

跨进程通信的底层是由Binder完成的,Binder IPC使用Client-Server通信方式。

Binder的工作原理

Binder是一个实体位于Server中的对象,该对象提供了一套方法。
Client获取Binder的引用就可以调用其提供的方法。
从通信的角度看,Client中的Binder也可以看作是Server Binder的‘代理’,在本地代表远端Server为Client提供服务。

Binder框架定义了四个角色:Server,Client,ServiceManager以及Binder驱动。其中Server,Client,ServiceManager运行于用户空间,驱动运行于内核空间。
这里写图片描述

和DNS类似,ServiceManager的作用是将字符形式的Binder名字转化成Client中对该Binder的引用。
因此Server向SMgr注册了Binder实体及其名字后,Client就可以通过名字获得该Binder的引用了。

ServiceManager

ServiceManager和其它进程同样采用Binder通信,ServiceManager是Server端,有自己的Binder对象(实体),其它进程都是Client,需要通过这个Binder的引用来实现Binder的注册,查询和获取。ServiceManager提供的Binder比较特殊,它没有名字也不需要注册,当一个进程使用。相对于ServiceManager其他进程无论是Client还是server,都可以认为是客户端,他们通过0号引用获得这个Binder与ServiceManager通信。

为什么说Binder只进行一次拷贝

在Linux中管道等方式通常两次拷贝:用户空间->内核空间->用户空间。
而Binder由Binder驱动负责管理数据接收缓存,通过mmap()把内存映射在用户空间的地址给驱动管理就是说。mmap()分配的内存除了映射进了接收方进程里,还映射进了内核空间。所以整个过程相当于做了一次从发送方用户空间到接收方用户空间的直接数据拷贝。

匿名共享内存

要知道,我们不能通过Binder传递太大的数据。官方文档里有说明,最大通常限制为1M。
一种共享内存的机制,它利用了Linux的mmap系统调用,将不同进程中的同一段物理内存映射到进程各自的虚拟地址空间,从而实现高效的进程间共享。它以驱动程序的形式实现在内核空间。Ashmem的两个特点就是共享和高效。
在Android中,主要提供了MemoryFile这个类来供应用使用匿名共享内存。在Android应用程序框架层,提供了一个MemoryFile接口来封装了匿名共享内存文件的创建和使用,通过JNI调用底层C++方法。

原创粉丝点击