Android Framework 学习(三):Android 跨进程通信机制

一、跨进程通信方式

跨进程通信主要有以下几类:管道、Socket、共享内存、信号。

1. 管道

管道的特点是半双工&单向的,管道里面的数据只能往一个方向流动。一般情况下管道是在父子进程之间使用的。

2.socket

socket的特点是全双工,即可读也可写。可以用在两个无亲缘关系的进程之间,但需要公开路径。

例子:

在Android的Framework机制中,zygote就是通过socket来接受AMS的请求,然后启动应用进程的。

3.共享内存

共享内存的特点:速度快,且不需要多次拷贝,且进程之间不需要存在亲缘关系,只需要拿到文件描述符即可。

这里补充一下:管道和socket的问题在于数据不能太大,否则性能会非常糟糕,相比较共享内存不存在这个问题。

4.信号

信号的特点是:

a).单向的,发送出去后不管其他人接受者是如何处理的;

b).只能带信号,不能带其他参数。

c).知道进程的pid就可以发信号,而且一次可以一群进程发信号(需 root权限 或 同uid 才行)。

例子:

Android的Process#killProcess方法,就是发送的 SIGNAL_KILL 信号。

5. Binder 

Binder机制是Android特有的进程间通信的机制,特点为:采用C/S的通信模式、有更好的传输性能,最重要的特点是安全。

下面我们就着重讲一下Android的Binder机制。

二、Binder的通信架构

Binder的通信架构示例如下图(示例的是系统服务,因为只有系统服务才能注册到ServiceManager):

1. 进程如何启动Binder机制

  • 首先打开binder驱动,binder驱动会给进程创立一套档案。
  • 然后将返回的描述符进行内存映射,分配缓存区。
  • 最后启动binder线程,binder线程会注册到binder驱动,同时线程进入loop循环,不断的跟binder驱动交互。

2. Binder机制的分层架构

Binder机制的分层架构如下图所示:

三、Binder机制的同步与异步

一般我们声明AIDL的时候,都是类似如下的方式,此方法是同步方法:

interface IPlayer {
    int getVolume();// 同步,假设执行1秒
}

其实我们也可以使用oneway来修饰AIDL内部的方法,修饰完成后就表示此方法是异步调用的。例如:

interface IPlayer {
    oneway void start();//异步,假设执行2秒
    oneway void stop();//异步,假设执行2秒
    int getVolume();// 同步,假设执行1秒
}

在上面的代码中,Client端调用IPlayer.start(),Server端的start需要执行2秒,由于定义的接口是异步的,Client端可以快速的执行IPlayer.start(),不会被Server端block住2秒。但是当Client端调用IPlayer. getVolume(),Server端的getVolume需要执行1秒,由于定义的接口是同步的,Client端在执行IPlayer. getVolume()的时候,会被Server端block住1秒。

为什么Android的Binder机制会提供同步/异步的调用机制呢?答:异步调用在不需要Server端的返回值或者状态的时候,能有效的提高Client的效率。

原文地址:https://www.cnblogs.com/renhui/p/12902191.html