Binder使用方式及常见组成及案例分析
Binder 是 Android 核心的跨进程通信IPC机制以一次内存拷贝、内置安全校验、面向对象接口为核心优势是系统服务与应用通信的基石。下面从核心组成、使用方式、实战案例、原理与常见问题四方面完整解析。一、Binder 核心组成C/S 模型Binder 采用经典的Client-Server-ServiceManager三角架构1. 核心角色四大组件ServiceManager服务管家系统唯一的 Binder 注册中心运行于init进程。负责服务注册addService与查询getService如ActivityManagerService、PackageManagerService均在此注册。Server服务端提供具体服务的进程内部持有Binder 实体BBinder实现业务逻辑。对外暴露IBinder接口供客户端绑定与调用。Client客户端发起请求的进程持有Binder 引用BpBinder/Proxy通过代理间接调用服务端方法。Binder Driver内核驱动运行于 Linux 内核是通信的 “中转站”。核心能力mmap 内存映射实现一次拷贝、线程池管理、UID/PID 身份校验、数据转发。2. 关键类与接口Java 层IBinderBinder 通信的顶层接口定义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 使用方式两种主流方案方式 1AIDL最常用跨应用 / 跨进程AIDLAndroid 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); }支持类型基本类型、String、List、Map、Parcelable自定义对象。步骤 2服务端实现CalculatorService.javapublic 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实体 } }注册 ServiceAndroidManifest.xmlservice android:name.CalculatorService android:process:remote/ !-- 独立进程 --步骤 3客户端调用ClientActivity.javaprivate 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.javapublic 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.javaServiceConnection 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);三、完整案例跨进程图书管理AIDLParcelable1. 定义 Parcelable 对象Book.javapublic 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用来创建数组比如跨进程返回 ListBook 时需要。 **/ public static final CreatorBook CREATOR new CreatorBook() { 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.aidlpackage com.example.binder; parcelable Book; // 声明Parcelable类型 interface IBookManager { void addBook(in Book book); ListBook getBookList(); }3. 服务端BookService.javapublic class BookService extends Service { private ListBook mBooks new ArrayList(); private final IBookManager.Stub mBinder new IBookManager.Stub() { Override public void addBook(Book book) { mBooks.add(book); } Override public ListBook getBookList() { return mBooks; } }; Override public IBinder onBind(Intent intent) { return mBinder; } }4. 客户端调用// 绑定后获取代理 IBookManager service IBookManager.Stub.asInterface(binder); service.addBook(new Book(1, Android开发艺术探索)); ListBook books service.getBookList();四、Binder 通信流程核心原理注册Server 创建BBinder实体通过addService()注册到ServiceManager。查询Client 通过getService()向ServiceManager请求服务获取BpBinder代理。调用Client 调用代理方法→transact()→驱动→ServeronTransact()→执行逻辑→返回结果→驱动→Client。内存驱动通过 mmap 映射内核缓冲区实现一次拷贝提升效率。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2497371.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!