当前位置: 首页 > news >正文

Binder使用方式及常见组成及案例分析

Binder 是 Android 核心的跨进程通信(IPC)机制,以一次内存拷贝内置安全校验面向对象接口为核心优势,是系统服务与应用通信的基石。下面从核心组成、使用方式、实战案例、原理与常见问题四方面完整解析。

一、Binder 核心组成(C/S 模型)

Binder 采用经典的Client-Server-ServiceManager三角架构:

1. 核心角色(四大组件)

  • ServiceManager(服务管家)
    • 系统唯一的 Binder 注册中心,运行于init进程。
    • 负责服务注册(addService)与查询(getService),如ActivityManagerServicePackageManagerService均在此注册。
  • Server(服务端)
    • 提供具体服务的进程,内部持有Binder 实体(BBinder),实现业务逻辑。
    • 对外暴露IBinder接口,供客户端绑定与调用。
  • Client(客户端)
    • 发起请求的进程,持有Binder 引用(BpBinder/Proxy),通过代理间接调用服务端方法。
  • Binder Driver(内核驱动)
    • 运行于 Linux 内核,是通信的 “中转站”。
    • 核心能力:mmap 内存映射(实现一次拷贝)、线程池管理UID/PID 身份校验数据转发

2. 关键类与接口(Java 层)

  • IBinder:Binder 通信的顶层接口,定义transact()queryLocalInterface()等核心方法。
  • Binder:服务端 Binder 实体的基类,实现IBinder,是BBinder的 Java 封装。
  • BinderProxy:客户端 Binder 引用,是BpBinder的 Java 封装,通过transact()发送跨进程请求。
  • Parcel:跨进程数据序列化容器,负责读写基本类型、Parcelable对象、IBinder等。
  • ServiceConnection:客户端绑定服务时的回调接口,用于获取IBinder对象。

3. AIDL 核心生成类(自动生成)

  • Stub:服务端继承的抽象类,继承自Binder,实现 AIDL 接口,处理onTransact()回调。
  • Proxy:客户端使用的代理类,封装BinderProxy,将方法调用转为transact()事务。

二、Binder 使用方式(两种主流方案)

方式 1:AIDL(最常用,跨应用 / 跨进程)

AIDL(Android Interface Definition Language)用于定义跨进程接口,编译器自动生成Stub(服务端)与Proxy(客户端)代码。

步骤 1:定义 AIDL 接口(ICalculator.aidl)
// main/aidl/com/example/binder/ICalculator.aidl package com.example.binder; interface ICalculator { int add(int a, int b); int subtract(int a, int b); }
  • 支持类型:基本类型、StringListMapParcelable自定义对象。
步骤 2:服务端实现(CalculatorService.java)
public class CalculatorService extends Service { private final ICalculator.Stub mBinder = new ICalculator.Stub() { @Override public int add(int a, int b) { return a + b; } @Override public int subtract(int a, int b) { return a - b; } }; @Override public IBinder onBind(Intent intent) { return mBinder; // 返回Binder实体 } }

注册 Service(AndroidManifest.xml):

<service android:name=".CalculatorService" android:process=":remote"/> <!-- 独立进程 -->

步骤 3:客户端调用(ClientActivity.java)

private ICalculator mService; private ServiceConnection mConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = ICalculator.Stub.asInterface(service); // 获取代理 try { int result = mService.add(10, 20); // 跨进程调用 } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { mService = null; } }; // 绑定服务 Intent intent = new Intent(this, CalculatorService.class); bindService(intent, mConn, BIND_AUTO_CREATE);

方式 2:原生 Binder(单应用多进程,轻量)

直接继承android.os.Binder,无需 AIDL,适合同应用内通信。

服务端(LocalService.java)
public class LocalService extends Service { public class LocalBinder extends Binder { public String getMessage() { return "Hello from LocalService"; } } private final IBinder mBinder = new LocalBinder(); @Override public IBinder onBind(Intent intent) { return mBinder; } }
客户端(LocalClient.java)
ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { LocalService.LocalBinder binder = (LocalService.LocalBinder) service; String msg = binder.getMessage(); // 直接调用 } }; bindService(new Intent(this, LocalService.class), conn, BIND_AUTO_CREATE);

三、完整案例:跨进程图书管理(AIDL+Parcelable)

1. 定义 Parcelable 对象(Book.java)

public class Book implements Parcelable { public int id; public String name; // 当一个 Book 对象从另一个进程传过来时,系统会把它变成一堆二进制数据(存在 Parcel 里)。 protected Book(Parcel in) { id = in.readInt(); name = in.readString(); } /** CREATOR 是系统用来 “自动重建对象” 的工具人 Android 系统在跨进程传输对象时,必须靠 CREATOR 才能把二进制数据还原成 Book 对象。 它干两件事: createFromParcel调用上面的 Book(Parcel in) 把数据还原成对象。 newArray用来创建数组,比如跨进程返回 List<Book> 时需要。 **/ public static final Creator<Book> CREATOR = new Creator<Book>() { @Override public Book createFromParcel(Parcel in) { // 调用上面的“拆包”构造方法 return new Book(in); } @Override public Book[] newArray(int size) { return new Book[size]; } }; @Override public int describeContents() { return 0; } // 从二进制数据里,把 id 和 name 读出来,重新拼成一个 Book 对象。 @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(id); dest.writeString(name); } }
2. AIDL 接口(IBookManager.aidl)
package com.example.binder; parcelable Book; // 声明Parcelable类型 interface IBookManager { void addBook(in Book book); List<Book> getBookList(); }
3. 服务端(BookService.java)
public class BookService extends Service { private List<Book> mBooks = new ArrayList<>(); private final IBookManager.Stub mBinder = new IBookManager.Stub() { @Override public void addBook(Book book) { mBooks.add(book); } @Override public List<Book> getBookList() { return mBooks; } }; @Override public IBinder onBind(Intent intent) { return mBinder; } }
4. 客户端调用
// 绑定后获取代理 IBookManager service = IBookManager.Stub.asInterface(binder); service.addBook(new Book(1, "Android开发艺术探索")); List<Book> books = service.getBookList();

四、Binder 通信流程(核心原理)

  1. 注册:Server 创建BBinder实体,通过addService()注册到ServiceManager
  2. 查询:Client 通过getService()ServiceManager请求服务,获取BpBinder代理。
  3. 调用:Client 调用代理方法→transact()→驱动→ServeronTransact()→执行逻辑→返回结果→驱动→Client。
  4. 内存:驱动通过 mmap 映射内核缓冲区,实现一次拷贝,提升效率。
http://www.jsqmd.com/news/609653/

相关文章:

  • 星际争霸2多智能体对战避坑指南:QMIX算法在5m_vs_6m地图上的调参实战
  • 3步打造专业级屏幕录制:面向创作者的开源解决方案
  • Creo许可证管理中的安全策略与隐私保护
  • UnrealEngine虚幻项目多人协作基石——Perforce局域网服务器搭建与避坑指南
  • Job调度延迟超标?深度解析Unity 2022.3+ Scheduler线程池饥饿问题,附可落地的4层负载均衡补丁代码
  • 保姆级教程:用Python和OpenCV动手实现一个简易视觉里程计(附代码)
  • Cross Q: Enhancing Deep Reinforcement Learning with Batch Normalization and Wide Critic Networks for
  • Python与Talib实战:如何高效计算CCI指标并可视化
  • Beyond Compare 5 许可证书生成与应用完全指南
  • Python AOT编译踩坑清单TOP 12:92%团队在__pycache__清理、CFFI绑定、asyncio事件循环冻结环节失败(含官方补丁patch链接)
  • 我让 Claude 和 Codex 同时审计 个模块,它们只在 个上达成共识环
  • Kandinsky-5.0-I2V-Lite-5s部署与调用:C语言开发者集成指南
  • TensorRT Int8量化实战避坑指南:标定数据、缓存与精度损失那些事儿
  • 从模型下载到API服务:手把手教你用MS-Swift+VLLM部署Qwen2.5-VL,打造自己的图像理解服务
  • Jenkins 学习总结傻
  • Jenkins 学习总结换
  • OpenClaw技能扩展实战:用Qwen3.5-9B自动处理Markdown文档
  • 在超大数据集下 DuckDB 与 MySQL 查询速度对比拥
  • 紧急预警:.NET 9 RC2中已移除的旧版Trimming API将导致边缘服务静默崩溃(立即检查你的.csproj!)
  • SpringCloud进阶--Seata与分布式事务耪
  • 计算机毕业设计:Python智慧气象数据采集分析系统 Flask框架 可视化 数据分析 机器学习 天气 深度学习 AI 空气质量分析(建议收藏)✅
  • 8634725
  • IP地址什么?工业场景网络注意事项有哪些?僬
  • 大模型转型必看:3个月速成模型大师,高薪跳槽指南,速收藏
  • 保姆级教程:手把手教你免费下载欧空局10米土地利用数据(附2020版避坑指南)
  • ARM 架构 JuiceFS 性能优化:基于 MLPerf 的实践与调优状
  • Rancher vs 原生K8s Dashboard:企业多集群管理到底该选谁?附详细功能对比与选型指南
  • VRM-Addon-for-Blender:跨平台3D模型格式转换解决创作者的兼容性痛点
  • 别再让CLIP/DINOv2在遥感图像上‘翻车’了:手把手教你用Earth-Adapter搞定卫星分割
  • MetalLB才是给Ingress这个老登做负重前行的那个男人棺