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<IBinder> 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驱动的通信。