本文原创作者: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.BinderInternaljclass 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.BinderProxyjclass 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
    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类型是Binderif (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对象的实际类型是BpBinderenv->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 proxysp<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对象,实际类型是JavaBBinderif (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对象指针//实际类型是本地框架里的BpBinderif (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框架的本地方法,流程如下图所示(若看不清请点击看大图):

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

  1. Binder机制详解(一)

    系列目录 Binder机制详解(二) Binder机制详解(三) 文章目录 前言 一.爱情例子 1.普通Linux间进程通信方式 2.接着讲爱情的例子(Binder的实现机制) 3.Binder少拷贝 ...

  2. Java类加载机制详解【java面试题】

    Java类加载机制详解[java面试题] (1)问题分析: Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数 ...

  3. Android FrameWork——Binder机制详解(1)

    1.前面我曾经发表过一篇blog介绍了aidl实现机制(aidl实现机制浅析),不过那只是停留在java表层,并遗留了一个问题,那就是BinderProxy.transact 该方法本地化实现,同时我 ...

  4. Android FrameWork——Binder机制详解(2)

    6.前面5个段落我主要说明了BinderProxy是如何把数据发送出去的,Ok,那么接下来,我们肯定想要知道服务端是怎么接收数据并传递给相应的BBinder进行处理的,有没有注意到前面waitForR ...

  5. 2020-Android大厂(字节跳动,腾讯,安卓binder机制详解

    我在大三的时候,没有参加春招,也没有参加秋招,我大三 三月份的时候在实习僧上投了几个简历,发现面的都很水,原来我在大学的时候,成绩还算ok,编程能力在班里也是前几的,但是说实话,找工作经验真的不足吧, ...

  6. java反射机制详解_JAVA反射机制详解_JSP/Java编程_互联网开发技术网_传播最新的编程技术_php361.com...

    今天,下午在和朋友聊天的时候,聊起了反射这个话题. 我们就从下面这个段简单的代码开始吧. 这个代码输出什么,想必大部分的读者跟我一样,会很快地知道答案:0 1 2 3 4 5 6 7 8 9.事实也是 ...

  7. Android 进阶——Framework 核心之Android Storage Access Framework(SAF)存储访问框架机制详解(二)

    文章大纲 引言 一.DirectFragment 1.当选中DirectoryFragment中RecyclerView的Item时 2.选中DirectoryFragment中RecyclerVie ...

  8. java 深拷贝_java 深拷贝与浅拷贝机制详解

    java 深拷贝与浅拷贝机制详解 概要: 在Java中,拷贝分为深拷贝和浅拷贝两种.java在公共超类Object中实现了一种叫做clone的方法,这种方法clone出来的新对象为浅拷贝,而通过自己定 ...

  9. 【java】SPI机制详解

    1.概述 以前的文章:[SPI]java基础之SPI框架实现 转载:Java常用机制 - SPI机制详解 PI(Service Provider Interface),是JDK内置的一种 服务提供发现 ...

  10. Android 进阶——Framework 核心之Android Storage Access Framework(SAF)存储访问框架机制详解(一)

    文章大纲 引言 一.Android Storage Access Framework 二.Storage Access Framework 的主要角色成员 1.Document Provider 文件 ...

最新文章

  1. iOS动画系列之九:实现点赞的动画及播放起伏指示器
  2. 爬墙技术哪家强,师范找锡伟
  3. 计算机视觉开源库OpenCV之查找轮廓函数cv2.findContours()介绍
  4. SpringBoot 2.1.3配置log4j2日志框架完整代码示例
  5. iOS基础知识点总结
  6. 微信小程序的线程架构
  7. php 系统交互 删除文件_FileSystemMap:与文件系统交互的自然方法
  8. 减小程序规模!稀疏数组Sparsearray,数据结构二维数组与稀疏数组转换,Java实现
  9. 导出mysql excel数据字典_mysql导出 Excel数据字典(全)
  10. 阿里达摩院发布2019十大科技趋势!AI专用芯片将挑战GPU的绝对统治地位
  11. 如何在 GitHub 上大显身手?
  12. 添加常见 URL Scheme 列表,方便快速查询⓶QA:URL Scheme适配好为何仍然报错
  13. Windows中安装ElasticSearch(单机+集群+Kibana)
  14. js动态修改onclick的响应函数后,IE无效的解决方案
  15. vb利用计算机 鸡兔同笼,VB程序题:利用计算机解决古代数学瓿“鸡兔同笼问题”。即已知在同一笼子里有总数为m只鸡和兔,鸡和兔的总脚数为n只,求鸡和兔各有多少只? VB源码 龚沛曾...
  16. 论文 | 研究方法 —— 结构方程
  17. 2013.07.10《播音主持之绕口令训练…
  18. 新人面试时候需要注意的写法
  19. CSS - 让整个页面变成灰色(一行代码)
  20. Android Studio 插件整理

热门文章

  1. 饿了么4年 + 阿里2年:研发路上的一些总结与思考
  2. Azure CDN 服务详解
  3. java jframe 设置背景图片_Java怎么给JFrame添加背景图片
  4. 用ESP8266连接 0.96寸 OLED屏幕
  5. 2021-2022 ICPC, NERC, Northern Eurasia Onsite C Connect the Points
  6. Presenting view controllers on detached view controllers is discouraged
  7. 阿里云服务器默认登录密码是什么?
  8. python如何控制运行时间_Python控制函数运行时间
  9. 跨年烟花 html 代码汇总
  10. 2021年物联网竞赛-A卷-ZigBee【CC2530】