一、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對象傳遞給其他進程 sp sm = 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對象 sp binder = 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機制。
原創文章,作者:BZWMW,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/372318.html