Binder机制源码分析
一、前言
Binder是Android系统中最重要的进程间通信机制,它不仅是应用程序和系统服务通信的基础,也是Android系统安全机制的重要组成部分。本文将深入分析Binder机制的实现原理,帮助读者理解Android系统的核心通信机制。
二、Binder基础概念
2.1 什么是Binder
定义与作用
- 进程间通信机制
- 基于C/S架构
- 支持同步和异步调用
优势特点
- 性能高效(一次拷贝)
- 安全可靠(身份校验)
- 使用简便(自动生成代码)
2.2 基本使用示例
// AIDL接口定义
// IBookManager.aidl
interface IBookManager {
List<Book> getBookList();
void addBook(in Book book);
}
// Book.aidl
parcelable Book;
// Book实现类
class Book : Parcelable {
var id: Int = 0
var name: String = ""
constructor(parcel: Parcel) {
id = parcel.readInt()
name = parcel.readString() ?: ""
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(id)
parcel.writeString(name)
}
override fun describeContents(): Int = 0
companion object CREATOR : Parcelable.Creator<Book> {
override fun createFromParcel(parcel: Parcel): Book {
return Book(parcel)
}
override fun newArray(size: Int): Array<Book?> {
return arrayOfNulls(size)
}
}
}
// Service实现
class BookManagerService : Service() {
private val bookList = mutableListOf<Book>()
private val binder = object : IBookManager.Stub() {
override fun getBookList(): List<Book> = bookList
override fun addBook(book: Book) {
bookList.add(book)
}
}
override fun onBind(intent: Intent): IBinder = binder
}
三、源码分析
3.1 Binder驱动
// frameworks/native/libs/binder/Binder.cpp
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
status_t err = data.errorCheck();
flags |= TF_ACCEPT_FDS;
if (err == NO_ERROR) {
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
}
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return err;
}
if ((flags & TF_ONE_WAY) == 0) {
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
} else {
err = waitForResponse(nullptr, nullptr);
}
return err;
}
3.2 ServiceManager
// frameworks/base/core/java/android/os/ServiceManager.java
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
3.3 AIDL编译生成的代码
// IBookManager.java (由AIDL自动生成)
public interface IBookManager extends android.os.IInterface {
public static abstract class Stub extends android.os.Binder
implements com.example.IBookManager {
private static final String DESCRIPTOR = "com.example.IBookManager";
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
public static com.example.IBookManager asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.example.IBookManager))) {
return ((com.example.IBookManager) iin);
}
return new com.example.IBookManager.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data,
android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getBookList: {
data.enforceInterface(DESCRIPTOR);
java.util.List<com.example.Book> _result = this.getBookList();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
// ...
}
return super.onTransact(code, data, reply, flags);
}
}
}
四、实战应用
4.1 自定义Binder接口
class RemoteService : Service() {
private val binder = object : IRemoteService.Stub() {
override fun getPid(): Int = Process.myPid()
override fun basicTypes(anInt: Int, aLong: Long, aBoolean: Boolean,
aFloat: Float, aDouble: Double, aString: String) {
// 实现基本类型的传输
}
}
override fun onBind(intent: Intent): IBinder = binder
}
class MainActivity : AppCompatActivity() {
private var remoteService: IRemoteService? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
remoteService = IRemoteService.Stub.asInterface(service)
try {
val pid = remoteService?.pid
Log.d(TAG, "Remote service pid: $pid")
} catch (e: RemoteException) {
e.printStackTrace()
}
}
override fun onServiceDisconnected(name: ComponentName) {
remoteService = null
}
}
}
4.2 死亡监听
class DeathRecipient : IBinder.DeathRecipient {
override fun binderDied() {
// 处理服务死亡事件
Log.e(TAG, "binder died")
remoteService = null
// 重新绑定服务
bindService()
}
}
// 注册死亡监听
remoteService?.asBinder()?.linkToDeath(deathRecipient, 0)
五、性能优化
数据传输优化
- 合理使用in、out、inout标记
- 避免传输大量数据
- 使用共享内存优化大数据传输
进程通信优化
- 合理使用oneway标记
- 避免频繁跨进程调用
- 实现进程间缓存机制
六、面试题解析
Binder通信机制的优势是什么?
- 性能方面:只需一次数据拷贝,性能优于传统IPC
- 安全方面:支持实名制通信,可以跟踪调用者身份
- 使用方面:基于面向对象思想设计,使用简单
Binder一次拷贝原理是什么?
- 传统IPC需要两次拷贝:用户空间→内核空间→用户空间
- Binder通过mmap实现内存映射,数据从用户空间拷贝到内核空间后,接收进程可直接访问
- 减少了一次数据拷贝,提高了性能
AIDL的实现原理是什么?
- AIDL文件会被编译器转换为Java接口文件
- 生成的接口包含Stub类(服务端)和Proxy类(客户端)
- Stub类继承Binder,实现接口方法
- Proxy类封装了跨进程通信的细节
七、开源项目实战
-
- 基于组件化的路由框架
- 使用AIDL实现跨进程组件通信
- 源码中的Binder使用值得学习
-
- Android应用虚拟化引擎
- 大量使用Binder进行进程通信
- Hook系统服务的实现方式
八、总结
通过本文的学习,我们深入理解了:
- Binder机制的工作原理
- 源码层面的实现细节
- AIDL的使用方法和原理
- 性能优化的关键点
Binder机制是Android系统的核心组成部分,深入理解Binder机制对于以下方面都有重要帮助:
- 理解Android系统架构
- 开发系统级应用
- 实现进程间通信
- 解决跨进程问题
下一篇,我们将分析Android系统的启动流程。