Android跨进程通信上:为什么选择Binder

656 阅读8分钟

Framework

Android系统分成三层:最上层是Application应用层,第二层是Framework层,第三层是Native层。
Android中的应用层和系统服务层不在同一个进程,系统服务在单独的进程中。

  • Android中不同应用属于不同的进程中。
  • Android应用和系统services运行在不同进程中是为了安全、稳定、以及内存管理的原因,但是应用和系统服务又需要通信和数据共享。

优点:

  • 安全性:每个进程都单独运行,可以保证应用层和系统层的隔离;
  • 稳定性:某个进程崩溃不会影响其他进程;
  • 内存分配:进程不需要时可以直接移除,回收对应内存。

程序中的多进程

虚拟机分配给各个进程的运行内存是有限制的,LMK也会优先回收对系统资源占用多的进程。

多进程的好处:

  1. 突破进程内存限制:如图库等大内存场景,因为内存分配是按进程来的。
  2. 功能稳定性:如独立的通信进程用于长连接,避免主进程被干扰。
  3. 规避系统内存泄漏:如WebView单独进程,避免泄漏拖垮主进程。
  4. 隔离风险:将不稳定的功能放入独立进程,保护主进程。

现实案例: 腾讯等大型应用内部一般会有多个进程同时运行。

image.png


Binder的出现

出身

Binder最早源自OpenBinder项目(由Be公司George Hoffman提出,Dianne Hackborn开发)。后来Dianne Hackborn加入Google,将OpenBinder理念移植到Android中,用来做进程通信。

为什么要学习binder

  1. startActivity时获取AMS服务,调用其startActivity方法;
  2. startActivity传递的对象为什么要序列化;
  3. bindService为什么回调的是一个binder对象;
  4. 多进程应用如何通信(AIDL的使用)。

Binder是什么?

Binder是Android中的“血管”。所有Activity、Service等组件与AMS(system server)的通信都需要通过Binder。

  • 机制:Binder是一种高效进程间通信(IPC)机制;
  • 驱动:Binder有内核驱动实现;
  • 应用层:Java/Native有相应的Binder类;
  • 整体架构:Binder把Client、Server、ServiceManager和Binder驱动连接起来,形成完整的C/S通信架构。

image.png


为什么选择Binder?

安卓中的常见IPC方式:

  1. 共享内存
    用于大块数据传递,如WS与SurfaceFlinger通信、ashmem机制。
    传大bitmap通过Intent时可能崩溃,是因为Intent禁掉fd,bitmap没法用共享内存,只能拷贝到Binder缓冲区导致超限;用putBinder可规避此问题。
  2. 管道
    父子进程通信,需要管道文件,数据是字节流格式,双向拷贝(进程到管道再到另一个进程)。
  3. 消息队列
    多进程共享内核链表,需约定数据格式和大小。
  4. Socket
    跨设备/进程通信,如AMS和zygote通信。
  5. 信号
    用于进程生命周期管理,通信能力极弱。
  6. Binder
    安卓官方主推,优势在于高效(一次拷贝),权限可控,支持多对多。

说明:所有这些通信方式都需要走内核空间。

Binder线程池:Server与Client通过Binder通信时,每个Client都会建立一个专用的通信线程(Binder线程池)。

各通信方式示意图

共享内存

image.png

管道

image.png

消息队列

image.png

Socket

image.png

Binder

image.png

方式对比

image.png


Binder通信的基本模型

内存划分

  • 内存被划分为用户空间和内核空间,两者隔离。即使用户程序崩溃,内核依然安全。

image.png


binder是如何管理的

  • Client端要与Server端通信,必须获取Server端的Binder。
  • Server通常先启动,并注册自身Binder到ServiceManager(SM)。
  • ServiceManager维护一个表,包含所有Server的Binder。
  • Client通过SM获取目标Binder,再进行通信。
  • ServiceManager的handle节点固定为0,类似DNS的8.8.8.8。

image.png
image.png


Binder是什么时候创建的?

  • Binder需要在App启动时第一时间创建,否则无法支持Activity等组件的跨进程通信。

image.png


跨进程通信模型

  • binder驱动属于Server端,在内核态。
  • Java代码通过AIDL生成Java和C++文件,打通Java/Native与Binder驱动通信。

image.png
image.png


stub/proxy 机制

  • stub是服务端存根,实现跨进程通信细节;
  • proxy是客户端代理,代理服务端Binder。

image.png

  • 跨进程调用需用stub的实现类(只有它实现了通信基础代码);
  • 客户端bindService时,用Action和package唯一确定服务器Binder对象。

image.png

  • ServiceConnection回调中的service其实就是服务端的Binder对象(IBinder接口,需要asInterface转换)。

image.png
image.png
image.png


服务注册完整流程

image.png
image.png


附:AIDL支持生成C++文件(Android 10+)

Android Q(29)及以后,AIDL支持直接生成C++,命令参考:
blog.csdn.net/yinminsumen…

学后检测

一、单选题

1. 下列关于Android进程与Binder通信的说法,正确的是:

A. Android所有应用都运行在同一个进程中
B. Binder是Android特有的进程内通信机制
C. 每个Android应用默认运行在独立进程
D. Android应用和系统服务之间的通信通常通过Binder完成

【答案与解析】

答案:D

解析:A错误,应用各自独立进程;B错误,Binder是IPC(进程间通信)不是进程内通信;C错误,应用可指定进程名,但通常一个应用进程可包含多个组件;D正确,App和系统服务间通信都依赖Binder。


2. 以下哪种不是Binder的直接优势?

A. 低拷贝高性能
B. 内核权限控制
C. 支持Java和C++层的跨进程通信
D. 能跨设备网络通信

【答案与解析】

答案:D

解析:Binder仅限本机进程间通信,不能跨设备。A、B、C都是Binder的优势。


3. Android中的ServiceManager的作用是什么?

A. 管理应用进程的生命周期
B. 管理所有已注册Binder服务的查找和分发
C. 处理Activity与Service的生命周期
D. 提供Java层到Native层的JNI桥接

【答案与解析】

答案:B

解析:ServiceManager是Binder架构中的“服务注册中心”,负责各服务的注册、查找和分发。


二、多选题

4. Android中采用多进程的常见场景包括哪些?

A. WebView内存泄漏隔离
B. 提高UI主线程流畅度
C. 突破单进程内存限制
D. 长连接独立、规避主进程崩溃
E. 系统组件(如AMS/PMS)与App分离

【答案与解析】

答案:A、C、D、E

解析:B选项不准确,多进程不是直接提升主线程流畅度的方法,其它选项均为实际应用场景。


5. 下列哪些属于进程间通信(IPC)方式?

A. 消息队列
B. 共享内存
C. Socket
D. 信号
E. Activity跳转

【答案与解析】

答案:A、B、C、D

解析:E不是IPC,A、B、C、D都是常见IPC机制。


6. 关于Binder机制的特点,以下说法正确的是?

A. 数据通过mmap只需一次拷贝
B. 每个Client通信会自动分配线程池
C. 可以对传输数据进行权限校验
D. 支持大容量bitmap数据无限制传输

【答案与解析】

答案:A、B、C

解析:D错误,binder数据大小受限(如1M-8K),传输大数据会失败。


三、判断题

7. 通过AIDL实现进程通信时,client和server端的aidl接口及包名路径必须完全一致。 ( )

A. 正确
B. 错误

【答案与解析】

答案:A

解析:只有接口、包名、方法一致,序列化反序列化才不会出错。


8. Binder机制支持Java和Native(C++)两种开发方式。 ( )

A. 正确
B. 错误

【答案与解析】

答案:A

解析:Android 10以后AIDL支持直接生成C++代码,Java/Native都支持。


9. Socket通信和Binder通信本质上都要经过内核空间。 ( )

A. 正确
B. 错误

【答案与解析】

答案:A

解析:所有IPC数据传递都需进出内核空间。


四、简答题

10. 请简述Binder相比传统IPC机制(如管道、消息队列、Socket)的优势。

【答案与解析】
  • 拷贝次数更少,借助mmap提升性能。
  • 支持权限校验、安全性高,适合多用户场景。
  • 线程池+驱动层支持高并发。
  • 统一服务注册/查找,便于系统服务管理和扩展。
  • 既可支持小对象高频RPC,又支持(有限)大对象共享。

11. 为什么传递大对象(如bitmap)时,Intent可能导致异常?如何规避?

【答案与解析】
  • Intent传递大对象时,若bitmap过大,不能走共享内存,只能拷贝到Binder缓冲区,容易超限(1M-8K),系统会抛出异常。
  • 正确做法:用文件共享或共享内存(ashmem)、或用putBinder(允许fd),规避Intent禁用fd机制的限制。

五、编程题

12. 设计一个多进程AIDL服务注册/通信的伪代码结构,说明Stub/Proxy的典型角色。

【答案与解析】

Server端:

// IMyAidlInterface.aidl
package com.example.aidl;
interface IMyAidlInterface {
    void doSomething();
}

// Service实现
public class MyService extends Service {
    private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {
        public void doSomething() { /* 业务实现 */ }
    };
    @Override
    public IBinder onBind(Intent intent) { return binder; }
}

Client端:

// ServiceConnection回调
public void onServiceConnected(ComponentName name, IBinder service) {
    IMyAidlInterface api = IMyAidlInterface.Stub.asInterface(service);
    api.doSomething();
}

Stub是服务端存根,Proxy是客户端远程代理,IBinder是两者通信的桥梁。


六、应用与原理分析题

13. 简要描述App通过Binder机制从启动到调用系统服务(如AMS)的典型时序流程。

【答案与解析】
  1. App启动时Zygote fork新进程,创建自身Binder实体。
  2. 系统服务(AMS/PMS等)启动后注册到ServiceManager。
  3. App进程通过ServiceManager获取系统服务的Binder引用。
  4. App通过Binder驱动将请求发往系统服务进程,由Binder线程池接收和分发。
  5. 系统服务处理后通过Binder驱动回传结果,完成一次完整的IPC调用。