您的位置:首页 > 编程语言 > Java开发

Binder 机制详解—Binder Java框架(转自Cloud Chou's Tech Blog)

2014-06-04 13:41 288 查看
本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接

本文转自Cloud Chou's Tech Blog , 原文地址:http://www.cloudchou.com/android/post-558.html

上一篇博客介绍了 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 类

1
2
3
4
5
6
7
8
9
10
11
12

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类

1
2
3
4
5
6
7
8

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类

1
2
3
4
5
6
7
8
9
10
11
1213
14
15
16
17

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对象

1
2
3
4
5
6
7
8
9
10
11
1213
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& 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<JavaBBinder*>(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
        sp<DeathRecipientList> drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);
        env->SetIntField(object, gBinderProxyOffsets.mOrgue, 
                    reinterpret_cast<jint>(drl.get()));
 
        // Note that a new object reference has been created.
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }
 
    return object;
}

2) ibinderForJavaObject 将Java层的IBinder对象转为本地IBinder对象

1
2
3
4
5
6
7
8
9
10
11
1213
14
15
16
17
18
19
20
21
22
23
24

sp<IBinder> ibinderForJavaObject(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框架的本地方法,流程如下图所示(若看不清请点击看大图):


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: