Files
mkdocs/docs/android面试/系统原理/Binder机制.md
2026-01-15 11:53:37 +08:00

4.7 KiB
Raw Blame History

Binder机制

目录


Binder原理

Binder 简介

// BinderAndroid 的进程间通信IPC机制
// - 基于 Linux 内核的驱动
// - 高性能
// - 安全性好
// - 一次拷贝

为什么使用 Binder

// 1. 性能:一次拷贝,比 Socket 快
// 2. 安全:基于 UID/PID 的身份验证
// 3. 易用:面向对象的接口
// 4. 稳定:内核驱动,稳定性好

Binder架构

架构图

┌─────────────┐
│  Client     │  ←─── 客户端进程
└──────┬──────┘
       │
┌──────▼──────┐
│   Proxy    │  ←─── 代理对象
└──────┬──────┘
       │
┌──────▼──────┐
│   Binder   │  ←─── Binder 驱动
└──────┬──────┘
       │
┌──────▼──────┐
│   Stub     │  ←─── 存根对象
└──────┬──────┘
       │
┌──────▼──────┐
│  Service   │  ←─── 服务端进程
└─────────────┘

核心组件

// 1. Binder 驱动Linux 内核模块
// 2. ServiceManager管理所有服务
// 3. Binder 代理:客户端代理对象
// 4. Binder 实体:服务端真实对象

Binder通信流程

通信流程

1. Client 调用 Proxy 方法
2. Proxy 将数据打包Parcel
3. 通过 Binder 驱动发送到 Service
4. Service 的 Stub 接收数据
5. Stub 解包数据,调用真实方法
6. 返回结果,反向传输

数据传递

// Binder 使用 Parcel 传递数据
// Parcel轻量级序列化机制

Parcel parcel = Parcel.obtain();
parcel.writeString("Hello");
parcel.writeInt(123);
parcel.setDataPosition(0);

String str = parcel.readString();
int num = parcel.readInt();
parcel.recycle();

AIDL

AIDL 定义

// AIDLAndroid Interface Definition Language
// 用于定义跨进程接口

// IMyService.aidl
interface IMyService {
    int add(int a, int b);
    void setData(String data);
}

AIDL 使用

// 服务端实现
public class MyService extends Service {
    private IMyService.Stub binder = new IMyService.Stub() {
        @Override
        public int add(int a, int b) {
            return a + b;
        }
        
        @Override
        public void setData(String data) {
            // 处理数据
        }
    };
    
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }
}

// 客户端使用
private ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        IMyService myService = IMyService.Stub.asInterface(service);
        int result = myService.add(1, 2);
    }
    
    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
};

Binder性能

性能优势

// 1. 一次拷贝:数据只拷贝一次
// 2. 内存映射:使用 mmap
// 3. 内核优化:内核驱动优化

性能对比

// Binder vs 其他 IPC
// - Socket两次拷贝性能差
// - 管道:两次拷贝,性能差
// - 共享内存:需要同步,复杂
// - Binder一次拷贝性能好

Binder源码分析

关键类

// IBinderBinder 接口
// BinderBinder 基类
// BinderProxyBinder 代理
// Parcel数据容器

关键流程

// 1. 服务注册ServiceManager.addService()
// 2. 服务获取ServiceManager.getService()
// 3. 数据传递:通过 Binder 驱动
// 4. 方法调用Proxy → Stub

面试常见问题

Q1: Binder 的原理?

答案:

  • 基于 Linux 内核的驱动
  • 使用内存映射mmap实现一次拷贝
  • 通过 Binder 驱动实现进程间通信

Q2: 为什么 Android 使用 Binder

答案:

  1. 性能好:一次拷贝
  2. 安全性:基于 UID/PID 验证
  3. 易用性:面向对象接口
  4. 稳定性:内核驱动

Q3: Binder 通信流程?

答案:

  1. Client 调用 Proxy
  2. Proxy 打包数据
  3. 通过 Binder 驱动发送
  4. Service 的 Stub 接收
  5. Stub 调用真实方法
  6. 返回结果

Q4: AIDL 的作用?

答案:

  • 定义跨进程接口
  • 自动生成 Proxy 和 Stub
  • 简化 Binder 使用

最后更新2024年