上一篇博客介绍了 Binder本地框架层,本篇博客将介绍Binder的java层框架。
Binder的java层框架
Binder的Java框架层包含以下类(frameworks/base/core/java/android/os):IBinder,Binder,IInterface,ServiceManagerNative,ServiceManager,BinderInternal,IServiceManager,ServiceManagerProxy。
Binder的Java框架层部分方法的实现在本地代码里,源码位于frameworks/base/core/jni。
先前博客《Binder service入门—Framework binder service》中ICloudMananger与Binder Java 框架层的类图如下图所示(若看不清,请点击看大图):
与Binder本地框架类似,声明的binder service接口必须继承自IInterface,这里ICloudManager继承自IInterface。与Binder 本地框架层不相同的是,Java层的IBinder接口直接继承自IInterface,而本地的IBinder类继承自RefBase。本地的IBinder有两个子类,BBinder和BpBinder,Java层的IBinder接口也有两个子类,Binder和BinderProxy。Java层服务端的CloudManager (binder service实体类) 直接继承自Binder类,并实现了binder service接口ICloudManager,而客户端的CloudManagerProxy类只需实现binder service接口ICloudManager即可。
Binder java层框架相关 Jni源码
Binder Java层框架类有不少方法是native的,意味着这些native方法是jni方法。Java层框架中的类Binder,BinderProxy,BinderInternal的native方法的实现是在源码frameworks/base/core/jni/android_util_Binder.cpp里,Java层框架中Parcel类native方法的实现是在frameworks/base/core/jni/android_os_Parcel.cpp里。接下来我们将详细分析android_util_Binder.cpp。
重要数据结构
1)gBinderOffsets,代表android.os.Binder 类
```cpp
static struct bindernative_offsets_t
{
// 指向class对象android.os.Binder
jclass mClass;
//指向 android.os.Binder的execTransact方法
jmethodID mExecTransact;
//指向android.os.Binder的mObject字段,
//将用于保存指向JavaBBinderHolder对象的指针
jfieldID mObject;
} gBinderOffsets;
```
2)gBinderInternalOffsets,代表com.android.internal.os.BinderInternal类
```cpp
static struct binderinternal_offsets_t
{
//指向 class对象com.android.internal.os.BinderInternal
jclass mClass;
//指向BinderInternal的forceGc方法
jmethodID mForceGc;
} gBinderInternalOffsets;
```
3)binderproxy_offsets_t,代表android.os.BinderProxy类
```cpp
static struct binderproxy_offsets_t
{
//指向 class对象android.os.BinderProxy
jclass mClass;
//指向 BinderProxy的构造方法
jmethodID mConstructor;
//指向 BinderProxy的sendDeathNotice方法
jmethodID mSendDeathNotice;
//指向 BinderProxy的mObject字段
jfieldID mObject;
//指向 BinderProxy的mSelf字段
jfieldID mSelf;
//指向 BinderProxy的mOrgue字段
jfieldID mOrgue;
} gBinderProxyOffsets;
```
4)JavaBBinder和JavaBBinderHolder
JavaBBinder和JavaBBinderHolder相关类类图如下所示(若看不清,请点击看大图),JavaBBinder继承自本地框架的BBinder,代表binder service服务端实体,而JavaBBinderHolder保存JavaBBinder指针,Java层Binder的mObject保存的是JavaBBinderHolder指针的值,故此这里用聚合关系表示。BinderProxy的mObject保存的是BpBinder对象指针的值,故此这里用聚合关系表示。
重要函数
1)javaObjectForIBinder 将本地IBinder对象转为Java层的IBinder对象,实际类型是BinderProxy
```cpp
jobject javaObjectForIBinder(JNIEnv* env, const sp& val)
{
if (val == NULL) return NULL;
//如果是 binder 服务端进程调用javaObjectForIBinder
//将调用JavaBBinder的object方法返回jobject,
//这里jobject的实际Java类型是Binder
if (val->checkSubclass(&gBinderOffsets)) {
// One of our own!
jobject object = static_cast(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\\n", val.get(),
object);
return object;
}
//如果是binder客户端进程,则需要返回Java层的BinderProxy对象
// For the rest of the function we will hold this lock, to serialize
// looking/creation of Java proxies for native Binder proxies.
AutoMutex _l(mProxyLock);
// 如果已有用Java层WeakReference保存的BinderProxy对象,则返回该对象
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL) {
jobject res = env->CallObjectMethod(object,
gWeakReferenceOffsets.mGet);
if (res != NULL) {
ALOGV("objectForBinder %p: found existing %p!\\n", val.get(),
res);
return res;
}
LOGDEATH("Proxy object %p of IBinder %p no longer
in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
//创建BinderProxy对象
object = env->NewObject(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mConstructor);
if (object != NULL) {
LOGDEATH("objectForBinder %p: created new proxy %p !\\n",
val.get(), object);
// The proxy holds a reference to the native object.
//设置BinderProxy对象的mObject字段为本地IBinder对象指针,
//本地IBinder对象的实际类型是BpBinder
env->SetIntField(object, gBinderProxyOffsets.mObject,
(int)val.get());
val->incStrong(object);
// The native object needs to hold a weak reference back to the
// proxy, so we can retrieve
//the same proxy if it is still active.
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
//关联gBinderProxyOffsets,故此第20行代码用findObject才能找到
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
// Also remember the death recipients registered on this proxy
spdrl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
env->SetIntField(object, gBinderProxyOffsets.mOrgue,
reinterpret_cast(drl.get()));
// Note that a new object reference has been created.
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
}
return object;
}
```
2)ibinderForJavaObject 将Java层的IBinder对象转为本地IBinder对象
```cpp
spibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
//如果是Java层Binder对象
//则将Binder对象的mObject字段转为JavaBBinderHolder指针
//然后调用它的get方法即可转为本地IBinder对象,实际类型是JavaBBinder
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetIntField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
//如果是Java层的BinderProxy对象,
//则将BinderProxy对象的mObject字段直接转为本地的IBinder对象指针
//实际类型是本地框架里的BpBinder
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
```
初始化流程
Java虚拟机启动时会调用jni方法来注册Java层binder框架的本地方法,流程如下图所示(若看不清请点击看大图):
感谢您的支持,我会继续努力的!
赏个5毛,支持我把
打开支付宝扫一扫,即可进行扫码打赏哦