一、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-hk/n/372318.html
微信掃一掃
支付寶掃一掃