前言
众所周知,对于binder通信来说,native层通信的基础架构是BpBinder/BBinder,Java层的基础通信架构是BinderProxy/Binder,这两者是如何统一起来的呢?
正文
在binder的跨进程传递数据实现中,数据是包裹在Parcel中的。具体的传递方式,体现在Parcel类的两个方法writeStrongBinder()和readStrongBinder()中,前者的功能是写入Binder对象,后者的功能是读取Binder对象。同样,Parcel在java层和native层各有一套。不过,查看代码可知,java层的Parcel只是native层的封装,两者通过jni建立关联。
代码语言:java复制 public final void writeStrongBinder(IBinder val){
nativeWriteStrongBinder(mNativePtr, val);
}
public final IBinder readStrongBinder(){
return nativeReadStrongBinder(mNativePtr);
}
private static native String nativeReadStrongBinder(long nativePtr);
private static native void nativeWriteStrongBinder(long natievPtr, IBinder);
jni层代码如下
代码语言:text复制
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL){
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR){
signalExceptionForError(env, clazz, err);
}
}
}
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL){
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
重点来了,在jni层代码中发现了两个名字起的有点意思的函数ibinderForJavaObject()和javaObjectForIBinder(),正是这两个函数,将java层和native层统一了,代码如下
代码语言:text复制 sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj){
if (obj == NULL) return NULL;
//Instance of Binder?
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)){
JavaBBinderHolder* jbh = (JavaBBinderHolder*)env->GetLongField(obj, gBinderOffsets.mObject);
return jbh->get(env, obj);
}
//Instance of BinderProxy?
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)){
return getBPNativeData(env, obj)->mObject;
}
return NULL;
}
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)){
//It's a JavaBBinder created by ibinderForJavaObject
jobject object = static_cast<JavaBBinder*>(val.get())->object();
return object;
}
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = val;
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mGetInstance, (jlong)nativeData, (jlong)val.get());
...
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
if (actualNativeData == nativeData){
//Created a new Proxy
...
} else {
delete nativeData;
}
return object;
}
ibinderForJavaObject()将java binder对象转换成native层binder对象,javaObjectForIBinder()将native binder对象还原成java层binder对象。
总结
android在创建java层Binder对象和BinderProxy对象时,会同时在native层创建对应的JavaBBinderHolder和BinderProxyNativeData。前者包含一个JavaBBinder类型的成员,它继承自BBinder;后者包含BpBinder对象。这样就把java层和native层的连接建立起来了。