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 框架层的类图如下图所示(若看不清,请点击看大图):
与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)相关推荐
- Binder机制详解(一)
系列目录 Binder机制详解(二) Binder机制详解(三) 文章目录 前言 一.爱情例子 1.普通Linux间进程通信方式 2.接着讲爱情的例子(Binder的实现机制) 3.Binder少拷贝 ...
- Java类加载机制详解【java面试题】
Java类加载机制详解[java面试题] (1)问题分析: Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数 ...
- Android FrameWork——Binder机制详解(1)
1.前面我曾经发表过一篇blog介绍了aidl实现机制(aidl实现机制浅析),不过那只是停留在java表层,并遗留了一个问题,那就是BinderProxy.transact 该方法本地化实现,同时我 ...
- Android FrameWork——Binder机制详解(2)
6.前面5个段落我主要说明了BinderProxy是如何把数据发送出去的,Ok,那么接下来,我们肯定想要知道服务端是怎么接收数据并传递给相应的BBinder进行处理的,有没有注意到前面waitForR ...
- 2020-Android大厂(字节跳动,腾讯,安卓binder机制详解
我在大三的时候,没有参加春招,也没有参加秋招,我大三 三月份的时候在实习僧上投了几个简历,发现面的都很水,原来我在大学的时候,成绩还算ok,编程能力在班里也是前几的,但是说实话,找工作经验真的不足吧, ...
- java反射机制详解_JAVA反射机制详解_JSP/Java编程_互联网开发技术网_传播最新的编程技术_php361.com...
今天,下午在和朋友聊天的时候,聊起了反射这个话题. 我们就从下面这个段简单的代码开始吧. 这个代码输出什么,想必大部分的读者跟我一样,会很快地知道答案:0 1 2 3 4 5 6 7 8 9.事实也是 ...
- Android 进阶——Framework 核心之Android Storage Access Framework(SAF)存储访问框架机制详解(二)
文章大纲 引言 一.DirectFragment 1.当选中DirectoryFragment中RecyclerView的Item时 2.选中DirectoryFragment中RecyclerVie ...
- java 深拷贝_java 深拷贝与浅拷贝机制详解
java 深拷贝与浅拷贝机制详解 概要: 在Java中,拷贝分为深拷贝和浅拷贝两种.java在公共超类Object中实现了一种叫做clone的方法,这种方法clone出来的新对象为浅拷贝,而通过自己定 ...
- 【java】SPI机制详解
1.概述 以前的文章:[SPI]java基础之SPI框架实现 转载:Java常用机制 - SPI机制详解 PI(Service Provider Interface),是JDK内置的一种 服务提供发现 ...
- Android 进阶——Framework 核心之Android Storage Access Framework(SAF)存储访问框架机制详解(一)
文章大纲 引言 一.Android Storage Access Framework 二.Storage Access Framework 的主要角色成员 1.Document Provider 文件 ...
最新文章
- iOS动画系列之九:实现点赞的动画及播放起伏指示器
- 爬墙技术哪家强,师范找锡伟
- 计算机视觉开源库OpenCV之查找轮廓函数cv2.findContours()介绍
- SpringBoot 2.1.3配置log4j2日志框架完整代码示例
- iOS基础知识点总结
- 微信小程序的线程架构
- php 系统交互 删除文件_FileSystemMap:与文件系统交互的自然方法
- 减小程序规模!稀疏数组Sparsearray,数据结构二维数组与稀疏数组转换,Java实现
- 导出mysql excel数据字典_mysql导出 Excel数据字典(全)
- 阿里达摩院发布2019十大科技趋势!AI专用芯片将挑战GPU的绝对统治地位
- 如何在 GitHub 上大显身手?
- 添加常见 URL Scheme 列表,方便快速查询⓶QA:URL Scheme适配好为何仍然报错
- Windows中安装ElasticSearch(单机+集群+Kibana)
- js动态修改onclick的响应函数后,IE无效的解决方案
- vb利用计算机 鸡兔同笼,VB程序题:利用计算机解决古代数学瓿“鸡兔同笼问题”。即已知在同一笼子里有总数为m只鸡和兔,鸡和兔的总脚数为n只,求鸡和兔各有多少只? VB源码 龚沛曾...
- 论文 | 研究方法 —— 结构方程
- 2013.07.10《播音主持之绕口令训练…
- 新人面试时候需要注意的写法
- CSS - 让整个页面变成灰色(一行代码)
- Android Studio 插件整理
热门文章
- 饿了么4年 + 阿里2年:研发路上的一些总结与思考
- Azure CDN 服务详解
- java jframe 设置背景图片_Java怎么给JFrame添加背景图片
- 用ESP8266连接 0.96寸 OLED屏幕
- 2021-2022 ICPC, NERC, Northern Eurasia Onsite C Connect the Points
- Presenting view controllers on detached view controllers is discouraged
- 阿里云服务器默认登录密码是什么?
- python如何控制运行时间_Python控制函数运行时间
- 跨年烟花 html 代码汇总
- 2021年物联网竞赛-A卷-ZigBee【CC2530】