一、Binder机制概述
Binder是一种进程间通信机制,它是Android系统中非常重要的一部分。在Android系统中,应用程序需要和设备驱动程序、系统服务等进程进行通信,这就需要使用到Binder机制。
Binder机制是基于线程的进程间通信机制。Android系统中的每个进程都有一个Binder驱动,它负责创建Binder对象并维护Binder对象之间的连接。通过Binder机制,不同的进程可以共享数据,实现共享内存,同时也可以进行RPC(远程过程调用)。
Binder驱动会在内核层面为每个Binder对象分配一个唯一的标识符——Binder物理地址(Binder node)。
二、Binder机制的实现
1、Binder对象
Binder对象是Android系统中的核心对象,它是进程间通信的基础。在Binder机制中,每个进程通过创建接口类(Binder类)实现一个Binder对象,在进程间通信时将Binder对象传递给其他进程。
在Java层,Binder类是AIDL(Android Interface Definition Language)文件编译后生成的Java类,所有的Binder接口定义都必须使用AIDL文件来定义。
// IMyAidlInterface.aidl文件 interface IMyAidlInterface { void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); } // IMyAidlInterface.java文件 public interface IMyAidlInterface extends android.os.IInterface { ... }
在C++层,Binder对象则是继承自BBinder的类,BBinder类实现了Binder对象的基本功能。
// IBinder.h文件 class IBinder : public IInterface { public: DECLARE_META_INTERFACE(Binder); virtual status_t transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) = 0; ... }; // BBinder.h文件 class BBinder : public BnBinder { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); ... };
2、Binder驱动
Binder驱动是Android系统中专门用来处理Binder对象的进程,它主要负责的是Binder对象之间的连接、维护和转发等工作。
Binder驱动会为每个进程提供一个Binder设备文件(/dev/binder),每个进程都必须通过/dev/binder文件与Binder驱动通信,进行Binder对象的创建、连接和通信等操作。
3、Binder节点
当进程创建一个Binder对象时,Binder驱动会为该Binder对象分配一个唯一的标识符——Binder节点(Binder node),用于区分不同的Binder对象。
Binder节点是唯一的长整型标识符,其内部存储表示为一个指针。在Java层,Binder节点实际上是Java对象的引用。
在C++层,Binder节点指向的是Binder对象的头部,包括一个指向Binder对象的引用计数、一个指向Binder对象的类型所在的引用计数表的指针,以及类型ID和事务ID。
三、Binder机制的使用
1、创建和传递Binder对象
在创建Binder对象和将Binder对象传递给其他进程时,需要使用相应的API接口来完成。
在Java层,创建Binder对象需要使用Binder类,将Binder对象传递给其他进程需要使用IBinder接口。
// 创建Binder对象 private final IBinder mBinder = new MyBinder(); // 将Binder对象传递给其他进程 Intent intent = new Intent(this, MyService.class); intent.putExtra("binder", mBinder); startService(intent);
在C++层,创建Binder对象需要使用BnXXX或BpXXX类,将Binder对象传递给其他进程需要使用IBinder接口。
// 创建Binder对象 class MyBinder : public BnMyInterface { ... }; // 将Binder对象传递给其他进程 spsm = defaultServiceManager(); sm->addService(String16("my_service"), new MyService());
2、Binder对象的连接和阻塞
在进程间通信过程中,连接相关的操作都是在Binder驱动中完成的。
当一个进程调用Binder对象的transact方法来与另一个进程进行通信时,如果此时另一个进程还没有准备好接受数据,那么当前进程就会被阻塞,直到另一个进程准备好接受数据。
在Java层,使用Binder类连接和阻塞Binder对象需要使用while循环,不断调用transact方法,直到连接成功。
// 连接Binder对象 mService = IMyInterface.Stub.asInterface(service); // 阻塞Binder对象 while (mService == null) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } mService = IMyInterface.Stub.asInterface(service); }
在C++层,使用IBinder接口连接和阻塞Binder对象需要使用IPCThreadState类,IPCThreadState类提供了很多阻塞式的连接和传输方法。
// 连接Binder对象 spbinder = defaultServiceManager()->getService(String16("my_service")); // 阻塞Binder对象 if (binder == nullptr) { binder = IPCThreadState::self()->waitForService(String16("my_service")); }
3、Binder对象的传输和接收
Binder对象的传输和接收都是通过Binder驱动来实现的,具体的传输和接收过程由驱动进行管理。
在Java层,向Binder对象发送数据需要创建Parcel对象,将需要传输的数据打包到Parcel中,然后通过transact方法将Parcel传递给另一个进程。接收数据时,需要在onTransact方法中解析Parcel对象,获取传输过来的数据。
// 发送数据 Parcel data = Parcel.obtain(); data.writeInt(123); data.writeLong(456); service.transact(1, data, null, 0); // 接收数据 @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case 1: { int arg1 = data.readInt(); long arg2 = data.readLong(); Log.d(TAG, "arg1: " + arg1 + ", arg2: " + arg2); break; } } return super.onTransact(code, data, reply, flags); }
在C++层,发送和接收数据需要使用Parcel类,具体的过程与Java层类似。Parcel类提供了读写基本类型和创建自定义数据结构的方法,可以方便地进行数据的传输和接收。
// 发送数据 Parcel data; data.writeInt32(123); data.writeInt64(456); binder->transact(1, data, &reply); // 接收数据 virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { case 1: { int32_t arg1 = data.readInt32(); int64_t arg2 = data.readInt64(); ALOGD("arg1: %d, arg2: %lld", arg1, arg2); break; } } return BBinder::onTransact(code, data, reply, flags); }
四、总结
本文介绍了Android系统中非常重要的一部分——Binder机制。Binder机制是进程间通信的核心机制,它可以实现进程间数据的共享和RPC等功能。我们从Binder机制的概述、实现和使用三个方面对Binder机制进行了详细阐述,希望能够帮助读者更好地理解和使用Binder机制。