天天看點

android java ibinder_Android系統--IBinder和BpBinder

IBinder和BpBinder

引言

總結之前學習的内容可以發現,對于ServiceManager,當想使用其服務的時候,我們首先引入了ServiceManagerProxy,再往上層可以發現是封裝了ServiceManager.java以及ServiceManagerNative.java來友善使用。

在建立ServiceManagerProxy的時候,我們是傳入了一個IBinder對象,然後借助其transact方法與Binder驅動進行通信。

接下來分析一下,IBinder的實作原理

IBinder

IBinder接口當中應當有與Binder一緻的接口方法,即實作指令的方法

public boolean transact(int code, Parcel data, Parcel reply, int flags)

throws RemoteException;

為了擷取IBinder對象,必須有一個新的類來擷取對象,即BinderInternal,而擷取的方法是:

public static final native IBinder getContextObject();

顯然在這裡也是繼續調用native方法,因為最終要與Binder驅動建立關聯:

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)

{

sp b = ProcessState::self()->getContextObject(NULL);

return javaObjectForIBinder(env, b);

}

可以看到這裡利用了ProcessState,調用的是getContextObject方法,而這個方法最終傳回的是一個BpBinder對象

BpBinder

IBinder隻是一個接口類,在Native層,有BpBInder來繼承,在java層有一個Binder.java當中的BinderProxy來實作的。

當在執行指令的時候,需要将指令通過JNI轉換,首先從Java層的Binder當中的BinderProxy開始,一直到JNI當中使用:

IBinder* target = (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);

來利用getLongField得到BpBinder的記憶體位址,進而繼續調用BpBinder的處理請求函數:

status_t BpBinder::transact(

uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

// Once a binder has died, it will never come back to life.

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來進行與Binder驅動的通信。