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驅動的通信。