这里想由这个方法引出今天要讨论的JavaBBinderHolder,JavaBBinder是什么东西。
先将点引申的东西,关于 Binder通信都知道本地服务是继承 Binder 的(如 ActivityManagerNative),从 service manager 拿的服务代理是 BinderProxy 对象,两者都继承自 IBinder。
//./frameworks//base/core/java/android/os/Binder.java
public class Binder implements IBinder{
...
public Binder(){
init();
}
final class BinderProxy implements IBinder{
...
}
}
可以看到在 Java 层,Binder 和 BinderProxy 同样继承自 IBinder,表示有跨进程通讯的能力。像 ActivityManagerNative这种服务都是继承自 Binder,而 BinderProxy 一般是在 native 层创建,表示远程服务的本地代理。
1.BinderProxy 与 BpBinder 关联。BinderProxy 内部有一个mObject 持有这个 BpBinder的句柄。而 BpBinder在 native 创建的时候会调用其attachObject()方法,将这个 BpBinder 对象保存在其内部的 ObjectHandler 内部的一个 Vector 内。这样 BpBinder.cpp 和 BinderProxy.java 都持有了对方。并且 BpBinder 内部持有了指向了这个服务的 handle。
2.Binder和 JavaBBinderHolder。Binder 的构造函数有一个init(),最终进行一个 JNI 调用
//android_util_Binder.cpp
static void android_os_Binder_init(JNIEnv* env, jobject obj){
JavaBBinderHolder* jbh = new JavaBBinderHolder();
//将这个 JavaBBinderHolder 对象的句柄保存在了 java 层 Binder的 long mObject;
env->SetLongField(obj, gBinderoffsets.mObject, (jlong)jbh);
}
const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, kBinderPathName);
//证明gBinderOffsets.mClass表示android.os.Binder 类
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
//证明gBinderOffsets.mObject表示 android.os.Binder的 long mObject
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
...
}
当利用这个 Binder 进行通信时,会
writeStrongBinder(IBinder val)@Parcel;
public class Parcel{
public final void writeStrongBinder(IBinder val){
nativeWriteStrongBinder(mNativePtr, val);
}
}
//.../frameworks//base/core/jni/android_os_Parcel.cpp
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object){
Parel* parcel = reinterpret_cast<parcel*>(nativePtr);
if(parcel != NULL) {
const status_t err = parcel->writeStrongBinder(iBinderForJavaObject(env, object));
}
}
因此写入这个 Parcel 的 IBinder 是这个iBinderForJavaObject(env,object)
//
//这个 obj 是 java 层传来的 IBinder 对象
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj){
if(env->IsInstanceOf(obj, gBinderOffsets.mClass)){
//走进来说明这个 obj是 Binder对象
//得到上面说的与这个 Binder 在 init()中 创建并且关联的 JavaBBinderHolder
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
//下面分析这个,可以得到一个 JavaBBinder 对象
return jbj !=NULL ? jbh->get(env, obj) : NULL;
}
if(env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)){
//分支表明obj 是 BinderProxy 对象
//得到 BinderProxy 关联的BpBinder
return (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
}
class JavaBBinderHolder : public RefBase{
public:
sp<JavaBBinder> get(JNIEnv* env, jobject obj){
sp<JavaBBinder> b = mBinder.promte();
if(b == null){
//创建一个 JavaBBinder 对象,内部持有这个 Binder 对象
b = new JavaBBinder(env, obj);
mBinder = b;
}
return b;
}
}
因此 Binder 内部持有 JavaBBinderHolder,JavaBBinderHolder 内部持有 JavaBBinder,JavaBBinder 内部持有 Binder
因为调用writeStrongBinder(IBinder)@Parcel.java后,如果这个 IBinder 是 Binder 类型,那么入参是 JavaBBinder(内部持有 Binder),如果这个 IBinder 对象是 BinderProxy,那么入参是 BpBinder。
为什么说是入参呢,因为writeStringBinder(IBinder)@Parcel.cpp 会将这个 IBinder 继续处理成用来进行跨进程通信的flat_binder_object对象。既然说到这里了,继续说点东西好了。
//.../frameworks//native/libs/binder/Parcel.cpp
//从上面可以看出,这个val 是代表 Binder 的 JavaBBinderHolder 或者代表 BinderProxy 的 BpBinder 对象
status_ Parcel::wroteStringBinder(const sp<IBinder>& val){
return flatten_binder(ProcessState::self(), val ,this);
}
status_t flatten_binder(const sp<ProcessState&, const sp<IBinder>& binder, Parcel* out){
flat_binder_object obj;
obj.flag = 0x7f | FLAT_BINDER_FLAG_ACCEPTE_FDS;
if(binder != NULL){
//一般进这个分支
IBinder *local = binder->remoteBinder();
//JavaBBinder 继承自 BBinder,BBinder 重写了 remoteBinder()这个虚方法,返回自身
//BpBinder继承自 IBinder,未重写 remoteBinder()这个虚方法
//因此如果 binder 是 JavaBBinder,则 local 不为 NULL,若 binder 是 BpBinder,local 为 NULL
if(!local){
//走这里说明是 BpBinder
BpBinder *proxy =binder->localBinder();
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_HANDLE;
obj.binder = 0;
obj.handle = handle;
obj.cookie = 0;
}else{
//走这个分支说明是 JavaBBinder
obj.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);
}
}else{
obj.type = BINDER_TYPE_BINDER;
obj.binder = 0;
obj.cookie = 0;
}
return finish_flatten_binder(binder, obj, out);
}
inline static status_t finish_flatten_binder(const sp<IBinder>&, const flat_binder_object& flat, Parcel* out)
{
return out->writeObject(flat, false);
}
下面看 flag_binder_object 的数据结构,这些数据结构一般都定义在内核文件中(goldfish/drivers/staging/android/uapi/binder.h)
//goldfish/drivers/staging/android/uapi/binder.h
struct flat_binder_object {
/* 8 bytes for large_flat_header. */
__u32 type;
__u32 flags;
/* 8 bytes of data. */
union {
binder_uintptr_t binder; /* local object */
__u32 handle; /* remote object */
};
/* extra data associated with local object */
binder_uintptr_t cookie;
};
从上面分析可以找到,
- 如果写入的是 Binder,在 native 转成 JavaBBinder 写入,此时type = BINDER_TYPE_BINDER, binder 与 cookie = 这个 JavaBBinder 对象
- 如果写入的是 BinderProxy,在 native 转成 BpBinder 写入,此时type = BINDER_TYPE_HANDLE, handle = 这个 BpBinder 指向的服务的 handle
关于这个 JavaBBinder 对象啊,充当了一个媒介作用,当 Binder 客户端的请求经由 Binder 驱动转发后,在 onTransact()@JavaBBinder收到。onTransact()@JavaBBinder 内部调用其起保存的 mObject,即 Binder.java 对象的execTransact(),然后execTransact()@Binder.java 调用具体实现类重写的onTransact(),如下图,以 AMS 为例