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

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 框架层的类图如下图所示(若看不清,请点击看大图):

java_binder_framework

与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
    12
    13
    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对象指针的值,故此这里用聚合关系表示。

    binder_java_jni

重要函数

  • 1) javaObjectForIBinder 将本地IBinder对象转为Java层的IBinder对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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
    12
    13
    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框架的本地方法,流程如下图所示(若看不清请点击看大图):

jni_funitioons
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Binder机制Android系统中一种进程间通信(IPC)的机制,用于在不同进程之间进行数据交换和通信。通过Binder机制Android应用程序可以实现进程间的数据共享和相互调用。 Binder机制基于C/S架构,主要由服务端、客户端和Binder驱动组成。服务端提供一个或多个服务,将其注册到Binder驱动中,并通过Binder对象发送和接收数据;客户端通过获取服务端的Binder对象,与其进行通信和交互;而Binder驱动负责管理Binder对象的创建、销毁和通信。 在Binder机制中,Binder对象充当了交互的桥梁。每个Binder对象都有一个唯一的标识符(具体是一个32位的整数),用于识别和查找对应的服务端。通过Binder对象,客户端和服务端可以进行方法调用、数据传输等操作。服务端通过Binder对象将数据发送给客户端,客户端通过Binder对象将数据传递给服务端。 Binder机制设计了多种数据结构来实现进程间通信,如BpBinder、BpRefBase、Parcel等。BpBinder负责处理进程间的通信,并通过Binder Proxy将方法调用转发给服务端;BpRefBase用于引用计数,确保对象在不再使用时能够正确释放;Parcel用于在进程间传递数据,可以实现序列化和反序列化。 总结来说,Android Binder机制Android系统中一种进程间通信的机制,通过Binder对象实现不同进程之间的数据交换和通信。通过服务端、客户端和Binder驱动的协作,应用程序可以实现进程间的数据共享和相互调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值