在Linux中,進(jìn)程間通信機(jī)制主要有D-BUS和OpenBinder兩種,在Android中,通過IBinder對(duì)OpenBinder進(jìn)行了封裝,IBinder通信機(jī)制是一個(gè)輕量級(jí)的遠(yuǎn)程過程調(diào)用機(jī)制,用于進(jìn)程內(nèi)和進(jìn)程間的高性能的通信。IBinder傳遞的數(shù)據(jù)被封裝在android.os.Parcel中。需要注意的是,android.os.Parcel并非一種通用的序列化機(jī)制,而是專為IBinder設(shè)計(jì)的。D-BUS通信機(jī)制由于Blue-Z協(xié)議棧的需求在Android局部進(jìn)行了使用。
在Android中,遠(yuǎn)程過程調(diào)用被封住到IBinder類中。在底層的實(shí)現(xiàn)上和處理器間的遠(yuǎn)程過程調(diào)用類似,如圖1-1所示為IBinder通信的類圖。

圖1-1 IBinder通信
IBinder:: transact()是IBinder接口中一個(gè)比較重要的方法,其原型如下:
virtual status_t transact( uint32_t code, //請(qǐng)求的ID號(hào)
const Parcel& data, //請(qǐng)求的參數(shù)
Parcel* reply, //返回的結(jié)果
uint32_t flags=0)=0; //標(biāo)識(shí)符
對(duì)開發(fā)者而言,Android目前只提供了FLAG_ONEWAY一種標(biāo)識(shí)符,表示調(diào)用者在發(fā)出請(qǐng)求后,立即返回,不必等待被調(diào)用者返回結(jié)果。在Binder驅(qū)動(dòng)中,目前提供了4種標(biāo)識(shí)符:
TF_ONE_WAY //調(diào)用者立即范圍,異步調(diào)用
TF_ROOT_OBJECT //數(shù)據(jù)為組件的根對(duì)象
TF_STATUS_CODE //數(shù)據(jù)為一個(gè)32bit的狀態(tài)碼
TF_ACCEPT_FDS //允許以文件標(biāo)識(shí)符的方式響應(yīng)
如果IBinder指向的是一個(gè)客戶端代理,那么IBinder:: transact()方法只是把請(qǐng)求發(fā)送給服務(wù)器。服務(wù)端的IBinder:: transact()方法則提供實(shí)際的服務(wù)。
在客戶端,BpBinder類是遠(yuǎn)程IBinder對(duì)象在本地進(jìn)程的一個(gè)代理,其transact()方法實(shí)現(xiàn)為:
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
//一旦一個(gè)binder被銷毀,將無(wú)法再被激活
if (mAlive) {
status_t status=IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status==DEAD_OBJECT) mAlive=0;
return status;
}
return DEAD_OBJECT;
}
其中IPCThreadState:: transact()會(huì)把請(qǐng)求經(jīng)內(nèi)核模塊發(fā)送給服務(wù)器端,服務(wù)器端處理完請(qǐng)求之后,沿原路將處理結(jié)果返給調(diào)用進(jìn)程。這里的請(qǐng)求是同步操作,它會(huì)等待直到結(jié)果返回為止。
在BpBinder之上進(jìn)行簡(jiǎn)單封裝,我們可以得到與服務(wù)對(duì)象相同的接口,調(diào)用者無(wú)須關(guān)心調(diào)用的對(duì)象是遠(yuǎn)程的還是本地的。此類實(shí)現(xiàn)在Android的多個(gè)場(chǎng)景獲得了應(yīng)用。與BpBinder類似的接口為BpRefBase,而BBinder則是一個(gè)本地對(duì)象。
在各種原生服務(wù)的實(shí)現(xiàn)上,通常會(huì)繼承BpRefBase的BpInterface接口來實(shí)現(xiàn)遠(yuǎn)程代理,繼承Bbinder的BnInterface接口來實(shí)現(xiàn)本地對(duì)象。
為了使C代碼也能調(diào)用Java實(shí)現(xiàn)的服務(wù),android_os_Binder_init里的JavaBBinder對(duì)Java 里的Binder對(duì)象進(jìn)行包裝。下面是JavaBBinder:: onTransact()方法的實(shí)現(xiàn):
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags=0)
{
JNIEnv* env=javavm_to_jnienv(mVM); //轉(zhuǎn)換Java
LOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
jboolean res=env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, (int32_t)&data, (int32_t)reply, flags);
jthrowable excep=env->ExceptionOccurred();
if (excep) {
report_exception(env, excep,
"*** Uncaught remote exception! "
"(Exceptions are not yet supported across processes.)");
res=JNI_FALSE;
//清除JNI的本地記數(shù)因子
env->DeleteLocalRef(excep);
}
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
JavaBBinder的實(shí)現(xiàn)位于android_util_Binder.cpp文件中。
IBinder不提供廣播消息,但通過ActivityManagerService服務(wù)可以實(shí)現(xiàn)廣播,觸發(fā)廣播需要調(diào)用 ActivityManagerProxy::broadcastIntent()方法,接收廣播消息需要首先實(shí)現(xiàn)接口BroadcastReceiver,然后調(diào)用 ActivityManagerProxy::registerReceiver()方法進(jìn)行注冊(cè)。