Android 进阶——Framework核心 之Binder Native成员类详解(二)

news2024/10/3 4:44:08

文章大纲

  • 引言
  • 一、Native 家族核心成员关系图
  • 二、Native 家族核心成员源码概述
    • 1、IInterface
      • 1.1、DECLARE_META_INTERFACE 宏
      • 1.2、IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 宏
      • 1.3、sp< IInterface > BnInterface< INTERFACE >::queryLocalInterface(const String16& _descriptor) 模板函数
      • 1.4、static sp< IBinder > asBinder(const IInterface*) 安全触发onAsBinder函数
    • 2、IBinder
    • 3、BBinder(Binder本地对象)
      • 3.1、transact 和onTransact函数
    • 4、BpBinder
      • 4.1、BpBinder构造函数
      • 4.2、mHandle 引用对象句柄
      • 4.3、transact( uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags = 0)
    • 5、BpRefBase
    • 6、BnInterface 和BpInterface
      • 6.1、BpInterface构造函数
    • 7、ProcessState 初始化binder设备
    • 8、IPCThreadState 负责与Binder驱动交互
    • 9、Binder 对象引用计数管理
    • 10、IInterface vs IBinder?

引言

上一篇文章总结了Binder IPC的相关理论,不过呢,和这篇文章关系不大,不存在先后的顺序,因为这篇文章是主要解读Binder 代码层面主要家族成员类功能和部分代码的,目的是从代码和逻辑设计对Binder 有更深的理解。

一、Native 家族核心成员关系图

Android 中Binder native 家族主要的头文件位于/frameworks/native/include/binder/,实现位于/frameworks/native/libs/binder/,这些代码最终会被编译成动态链接库libbinder.so(即Binder库),供其他进程调用。

find -type f -name “*.mk” | xargs grep “keyword”

主要有 IBinder、BBinder、BpBinder、BnInterface、BpInterface、IInterface类

在这里插入图片描述

二、Native 家族核心成员源码概述

Android中Java 、Native层使用同一套架构实现Binder服务,Java层通过JNI调用Native 层的实现,Binder 底层不需要关心上层的实现细节,只需要和BBinderBpBinder通信即可。BpBinder和BBinder是具有映射的关系,BpBinder为客户端BBinder为服务端,BpBinder通过前面所说的handle去标识其对应的客户端BBinder。

1、IInterface

\frameworks\native\include\binder\IInterface.h 、\frameworks\native\libs\binder\IInterface.cpp

IInterface是为客户端进程的上层应用提供接口服务的基类接口并继承了RefBase,通常其派生类实现了Binder服务的业务方法,通过这个接口客户端进程的上层应用能像使用本地对象一样直接使用远程的BBinder提供的Binder服务。简而言之,Binder代理对象主要负责与应用程序通信,与引用对象互相独立,代理对象可以有很多个实例但是指向的是同一个Binder引用对象。

1.1、DECLARE_META_INTERFACE 宏

执行DECLARE_META_INTERFACE 宏时添加:静态成员变量descriptor、静态函数asInterface()以及类的构造函数和析构函数,自己在native 开发Binder时也可以直接使用。

#define DECLARE_META_INTERFACE(INTERFACE) \
    static const String16 descriptor; \
    static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \
    virtual String16 getInterfaceDescriptor() const; \

I##INTERFACE##表示连接两个宏定义,而INTERFACE是模板名,被当作是宏定义,若INTERFACE被ServiceManager替代则I##INTERFACE就是IServiceManager

其中asInterface()函数主要是用于把Binder引用(BpBinder的派生类)转成代理对象(IInterface派生类),在客户进程中执行则会新建一个Binder代理对象(里面包含了引用对象);在服务端进程中则直接返回参数的指针,因为在服务端进程中可以直接通过指针调用服务类,无需通过代理对象去调用了。

1.2、IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 宏

初始化了一个变量descriptor,实现了I##INTERFACE2个函数:getInterfaceDescriptor ()和 asInterface()

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
    const String16 I##INTERFACE::descriptor(NAME); \
    String16 I##INTERFACE::getInterfaceDescriptor() const { \
        return I##INTERFACE::descriptor; \
    } \
    sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \
    { \
        sp<I##INTERFACE> intr; \
        if (obj != NULL) { \
            intr = static_cast<I##INTERFACE*>( \
                obj->queryLocalInterface( \
                        I##INTERFACE::descriptor).get()); \
            if (intr == NULL) { \
                intr = new Bp##INTERFACE(obj); \
            } \
        } \
        return intr; \
    }

\ 则表示一行的结束标志

1.3、sp< IInterface > BnInterface< INTERFACE >::queryLocalInterface(const String16& _descriptor) 模板函数

根据传入的字符串描述符查询对应的IInterface 对象。

1.4、static sp< IBinder > asBinder(const IInterface*) 安全触发onAsBinder函数

本质上就是调用传入的形参的onAsBinder函数。

2、IBinder

Base class and low-level protocol for a remotable object.

IBinder继承自RefBase是所有可远程通信对象的基类,定义了最底层的通信协议,Java 层的IBinder的能力本质上就是native 层IBinder提供的。

RefBase(BpRefBase继承自RefBase) 是Android 智能指针相关的引用计数基类,继承了RefBase 的派生类对象可以通过强、弱指针维护其生命周期。

3、BBinder(Binder本地对象)

frameworks\native\include\binder\Binder.h,\frameworks\native\libs\binder\Binder.cpp

BBinder直接继承自IBinder,Binder 服务能力的提供者(服务端Binder对象),实现了抽象的IPC 通用通信接口——transact函数。一个提供Binder服务的类必须继承BBinder,BBinder 是服务端的中心,真正的函数实现是在BBinder的派生类中。

3.1、transact 和onTransact函数

BBinder 主要负责和底层的IPCThread 通信,当一个Binder代理对象通过Binder驱动向一个Binder本地对象发出一个IPC调用时,Binder驱动的IPCThread会调用BBinder的transact函数,进而触发onTransact 函数来分发与业务相关的IPC。当Binder调用从Binder驱动传递过来时,IPCThread 会调用BBinder的transact函数。

4、BpBinder

\frameworks\native\include\binder\BpBinder.h、\frameworks\native\libs\binder\BpBinder.cpp

BpBinder 是BBinder 对象在客户端进程的引用对象,客户端直接通过使用BpBinder来获得远程对象的能力。

4.1、BpBinder构造函数

BpBinder::BpBinder(int32_t handle)
    : mHandle(handle)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(NULL)
{
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    IPCThreadState::self()->incWeakHandle(handle);
}

创建IPCThreadState对象并增加自身的弱引用计数。

4.2、mHandle 引用对象句柄

在BpBinder中有一个**int32_t类型的成员变量,存储的是Client组件对应Binder驱动中的Binder引用对象的句柄,**成员函数handle() 的返回值就是这个句柄。

每一个Client组件在Binder驱动都对应着一个Binder 引用对象,Client组件就是通过这个句柄值和Binder驱动中的Binder引用对象建立映射关系的。

4.3、transact( uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags = 0)

transact 函数主要用于向Server进程的Server组件发送IPC请求。当向Server 组件发起IPC 请求时,会把BpBinder类的mHandle和通信数据一起发给Binder驱动,Binder驱动根据mHandle句柄先找到Binder引用对象,进而找到对应的Binder实体对象,最后将通信数据通过映射内存方式发送给对应的Server组件。

5、BpRefBase

而BpRefBase中间接持有BpBinder对象:通过调用remote函数就可以获取。

6、BnInterface 和BpInterface

\frameworks\native\include\binder\IInterface.h头文件下还定义了两个Binder库中重要的模板类。

Binder库成员代称角色关联的Binder驱动对象
BnInterfaceBinder本地对象作为Server组件Binder实体对象
BpInterfaceBinder代理对象作为Client组件Binder引用对象
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;
protected:
    virtual IBinder*            onAsBinder();
};

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
                                BpInterface(const sp<IBinder>& remote);
protected:
    virtual IBinder*            onAsBinder();
};

INTERFACE是一个自定义的Server组件接口占位符

BnInterface 继承了BBinder和INTERFACE,而BBinder 直接继承自IBinder。

6.1、BpInterface构造函数

BpInterface声明在IInterface.h中,是一个模板类,remote初始化了其父类BpRefBase并把remote保存父类BpRefBase的成员变量mRemote中。

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{
}

而构造函数为

BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)
{
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);

    if (mRemote) {
        mRemote->incStrong(this);
        mRefs = mRemote->createWeak(this);
    }
}

mRemote就等于之前的new Bpbinder。

7、ProcessState 初始化binder设备

篇幅问题,详情参见下文。

8、IPCThreadState 负责与Binder驱动交互

篇幅问题,详情参见下文。

9、Binder 对象引用计数管理

篇幅问题,详情参见下文。

10、IInterface vs IBinder?

留一个疑问给大家自己思考,未完待续…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/337660.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微前端qiankun架构 (基于vue2实现)使用教程

工具使用版本 node --> 16vue/cli --> 5 创建文件 创建文件夹qiankun-test。 使用vue脚手架创建主应用main和子应用dev 主应用 安装 qiankun: yarn add qiankun 或者 npm i qiankun -S 使用qiankun&#xff1a; 在 utils 内创建 微应用文件夹 microApp,在该文件夹…

_Linux (线程池)

文章目录线程池概述&#xff1a;线程池示例&#xff1a;代码细节代码结果展示线程池概述&#xff1a; 一种线程使用模式。 线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&#xff0c;等待着监督管理者分配可并发执行的任务。这避…

Linux下文档类型转PDF的总结

我的环境 centos8 先说思路:先把字体上传到服务器,然后更新字体库 ,代码里面配置字体地址。 如果导出的还是乱码,要么没字体,要么检查代码里面的路径。 目录 1.上传windows字体到linux 2.建立索引信息,更新字体缓存

【基于ChatGPT+Python】快速打造前后端分离的OpenAI人工智能聊天机器人

&#x1f680; ChatGPT是最近很热门的AI智能聊天机器人 &#x1f680; 用途方面相比于普通的聊天AI更加的广泛&#xff0c;甚至可以帮助你改BUG&#xff0c;写代码&#xff01;&#xff01;&#xff01; &#x1f680; 下面是使用pythonChatGPTVue实现的在线聊天机器人&#xf…

shell脚本免交互与expect

目录 Here Document 定义 格式 注意 例子 统计行数 修改密码​编辑 expect 定义 基本命令 实验 免交互ssh主机 Here Document 定义 使用I/O重定向的方式将命令列表提供给交互式程序 格式 命令<< 标记....标记 注意 标记可以使用任意的合法字符&#xf…

SpringBoot笔记【JavaEE】

SpringBoot概念、创建和运行 1.什么是SpringBoot&#xff1f;为什么学习SpringBoot&#xff1f; Spring Boot 就是 Spring 框架的脚⼿架&#xff0c;它就是为了快速开发 Spring 框架⽽诞⽣的。 2.Spring Boot优点 快速集成框架【提供启动添加依赖的功能】内容运行容器【无需…

从零开始,打造属于你的 ChatGPT 机器人!

大家好&#xff01;我是韩老师。不得不说&#xff0c;最近 OpenAI/ChatGPT 真的是太火了。前几天&#xff0c;微软宣布推出全新的 Bing 和 Edge&#xff0c;集成了 OpenAI/ChatGPT 相关的技术&#xff0c;带动股价大涨&#xff1a;微软市值一夜飙涨 5450 亿国内外各家大厂也是纷…

为什么神经网络做不了2次函数拟合,网上的都是骗人的吗?

环境&#xff1a;tensorflow2 kaggle 这几天突发奇想&#xff0c;用深度学习训练2次函数。先在网上找找相同的资料这方面资料太少了。大多数如下&#xff1a; 。 给我的感觉就是&#xff0c;用深度学习来做&#xff0c;真的很容易。 网上写出代码分析的比较少。但是也找到了…

云计算|OpenStack|社区版OpenStack安装部署文档(十二--- openstack的网络模型解析---Rocky版)

前言&#xff1a; https://zskjohn.blog.csdn.net/article/details/128846360 云计算|OpenStack|社区版OpenStack安装部署文档&#xff08;六 --- 网络服务neutron的安装部署---Rocky版&#xff09; &#xff08;######注&#xff1a;以上文章使用的是openstack的provider网…

【Vue3】电商网站吸顶功能

头部分类导航-吸顶功能 电商网站的首页内容会比较多&#xff0c;页面比较长&#xff0c;为了能让用户在滚动浏览内容的过程中都能够快速的切换到其它分类。需要分类导航一直可见&#xff0c;所以需要一个吸顶导航的效果。 目标:完成头部组件吸顶效果的实现 交互要求 滚动距离大…

计算机视觉 对比学习13篇经典论文、解读、代码

为了快速对 机器视觉中的对比学习有一个快速了解&#xff0c;或者后续复习&#xff0c;此处收录了 13篇经典论文、一些讲解地较好的博客和相应的Github代码&#xff0c;用不同颜色标记。 ​ 对比学习 13篇经典论文 论文代码和博客http://​www.webhub123.com/#/home/detail?p…

Nextjs了解内容

目录Next.jsnext.js的实现1&#xff0c;nextjs初始化2&#xff0c; 项目结构3&#xff0c; 数据注入getInitialPropsgetServerSidePropsgetStaticProps客户端注入3&#xff0c;CSS Modules4&#xff0c;layout组件5&#xff0c;文件式路由6&#xff0c;BFF层的文件式路由7&…

爬虫笔记之——selenium安装与使用(1)

爬虫笔记之——selenium安装与使用&#xff08;1&#xff09;一、安装环境1、下载Chrome浏览器驱动&#xff08;1&#xff09;查看Chrome版本&#xff08;2&#xff09;下载相匹配的Chrome驱动程序地址&#xff1a;https://chromedriver.storage.googleapis.com/index.html2、学…

vue83-103

vue全局路由拦截路由懒加载路由原理swiper组件选项卡封装电影导航组件正在热映获取数据渲染axios封装详情渲染详情轮播详情Header-组件影院组件渲染全局路由拦截 即使路径对&#xff0c;也会被拦截 router.beforeEach((to,from, next) > { console.log(to) if&#xff08;…

雅思经验(9)

写作&#xff1a;关于趋势的上升和下降在小作文中&#xff0c;真的是非常常见的&#xff0c;所以还是要积累一下。下面给出了很多词&#xff0c;但是在雅思写作中并不是词越丰富&#xff0c;分数就越高的。雅思写作强调的是准确性&#xff1a;在合适的地方用合适的词和句法。不…

【数据库】 数据库中表的基本操作

目录 表的基本操作 一&#xff0c; 创建表 1&#xff0c;单行命令创建表&#xff1a; 2&#xff0c;分行命令创建表&#xff1a; 二&#xff0c; 数据类型 1&#xff0c;文本类型&#xff1a; 2&#xff0c;数值类型&#xff1a; 3&#xff0c;日期/时间类型&#xff1a…

软件测试金融测试岗位,本人亲面

网上银行转账是怎么测的&#xff0c;设计一下测试用例。 回答思路&#xff1a; 宏观上可以从质量模型&#xff08;万能公式&#xff09;来考虑&#xff0c;重点需要测试转账的功能、性能与安全性。设计测试用例可以使用场景法为主&#xff0c;先列出转账的基本流和备选流。然…

一个图片对比的小工具【小工具制作】

目录逐一击破确定架构图片上传自适应生成对比界面切换对比模式打分功能审核进行提交项目负责人查看问题并改正总结前言&#xff1a;这是一个实际的需求&#xff0c;因为需要设计师给的原图和同学们制作出来的项目成品图进行比对打分&#xff0c;所以就有了一个图片对比的小工具…

用 Python 调用 GPT-3 API

用 Python 调用 GPT-3 API GPT-3 是去年由 Open AI 推出的语言机器学习模型。它因其能够写作、写歌、写诗&#xff0c;甚至写代码而获得了广泛的媒体关注&#xff01;该工具免费使用&#xff0c;只需要注册一个电子邮件即可。 GPT-3 是一种叫 transformer 的机器学习模型。具体…

C语言(输入printf()函数)

printf()的细节操作很多&#xff0c;对于现阶段的朋友来说&#xff0c;主要还是以理解为主。因为很多的确很难用到。 目录 一.转换说明&#xff08;占位符&#xff09; 二.printf()转换说明修饰符 1.数字 2.%数字1.数字2 3.整型转换字符补充 4.标记 -符号 符号 空格符…