IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android-深入理解Binder(一) -> 正文阅读

[移动开发]Android-深入理解Binder(一)

深入理解Binder

1. 概述

??Binder是Android系统提供的一种IPC机制(进程间通信),由于Android是基于Linux内核的,因此除了Binder以外,还存在其他的IPC机制,如管道和Socket等。Android系统基本上可以看作是一个基于Binder通信的C/S架构,Binder就像是网络一样,把系统的各个部分连接在了一起,因此它是非常重要的。
在Binder通信的C/S架构体系中,除了C/S架构所包括的Client端和Server端外,Android还有一个全局的ServiceManager端,它的作用是管理系统中的各种服务。
在这里插入图片描述
??1.一个Server进程可以注册多个Service。
??2.Server进程要先注册一些Service到ServiceManager中,所以Server是ServiceManager的客户端,而ServiceManager就是服务端。
??3.如果某个Client进程要使用某个Service,必须先到ServiceManager中获取该Service的相关信息,所以Client是ServiceManager的客户端
??4.Client根据得到的Service信息与Service所在的Server进程建立通信的通路,然后就可以直接与Service交互了,所以Client也是Server的客户端。
??5.三者的交互都是基于Binder通信的,所以通过任意两者之间的关系,都可以揭示Binder的奥秘。

??Binder通信与C/S架构之间的关系,Binder只是为C/S架构提供了一种通信的方式,我们完全可以采用其他IPC方式进行通信,例如中有很多其他的程序就是采用Socker或者Pipe方式进行进程间通信的。

2. 解析MediaServer

??MediaServer简称MS,是一个用C++编写的可执行程序,因为这个Server是系统诸多重要Service的栖息地:
??1.AudioFlinger:音频系统中的核心服务
??2.AudioPolicyService:音频系统中关于音频策略的重要服务
??3.MediaPlayerService:多媒体系统中的重要服务
??4.CameraService:有关摄像/照相的重要服务

2.1 MediaServer的入口函数

??MS是一个可执行程序,入口函数是main,代码如下:
在这里插入图片描述

2.2 ProcessState

??我们在main函数的开始就遇到了ProcessState,由于每一个进程只有一个ProcessState,所以他是独一无二的,调用方式如下:
在这里插入图片描述
1.单例的ProcessState
在这里插入图片描述
??self函数采用了单例模式,每个进程只有一个ProcessState对象

2.ProcessState的构造
??ProcessState的构造函数打开了Binder设备
在这里插入图片描述
3.打开binder设备
??open_driver的作用就是打开/dev/binder这个设备,它是Android在内核中为完成进程间通信而专门设置的一个虚拟设备,实现如下:
在这里插入图片描述
Process::self函数就分析完了,总结如下:
??1.打开/dev/binder设备,这就相当于与内核的Binder驱动有了交互的通道
??2.对返回的fd使用mmap,这样Binder驱动就会分配一块内存来接受数据
??3.由于ProcessState具有唯一性,因此一个进程只会打开设备一次

2.3 defaultServiceManager

??1.defaultServiceManager函数的实现在IServiceManager.cpp中完成,它会返回一个IServiceManager对象,通过这个对象,我们可以同另一个进程ServiceManager进行交互。
在这里插入图片描述
??调用了ProcessState的getContextObject函数,这里传给它的参数是NULL,代码如下:
在这里插入图片描述
??getStrongProxyForHandle调用参数名叫做handle,在Windows编程中经常使用这个名称,是对资源的一种标识,其实就是有一个资源项,保存在一个资源数组,handle的值正是该资源项在数组中的索引。
在这里插入图片描述
2.BpBinder
??BpBinder和BBinder都是Android中与Binder通信相关的代表,都是从IBinder类中派生出来的。
在这里插入图片描述
??1.BpBinder是客户端用来与Server交互的代理类,p即Proxy代理的意思。
??2.BBinder则是与proxy相对的一端,它是proxy交互的目的端,如果Proxy代表客户端,那么BBinder则代表服务器,这里的BpBinder和BBinder是一一对应的,即某个BpBinder只能和对应的BBinder交互,我们也不希望BpBinderA发送的请求,却由BBinderB来处理。

??刚才我们在defaultService Manager()函数中创建了这个BpBinder。
问题一:为什么创建的不是BBinder?
??因为我们是ServiceManager的客户端,当然得使用代理端与ServiceManager进行交互
问题二:BpBinder和BBinder是一一对应的,那么BpBinder如何标识它对应的BBinder端呢?
??答案是Binder系统通过handler来标识相应的BBinder,我们给BpBinder构造函数传的参数handle的值是0,这个0在整个Binder系统中有重要含义,因为0
代表的就是ServiceManger所对应的BBinder。

BpBinder代码如下:
在这里插入图片描述
在这里插入图片描述
??这里的interface_cast其实是一个障眼法

3.interface_cast
??interface_cast,dynamic_cast和static_cast看起来是否非常眼熟?它们是指针类型转换的意思吗?如果是,那又是如何将BpBinder类型强制转化为IServiceManager类型呢?
interface_cast的具体实现:
在这里插入图片描述

4.IServiceManager
??IServiceManager定义了ServiceManager所提供的服务
在这里插入图片描述
??Android巧妙的通过DECLARE_META_INTERFACE和IMPLENT宏,将业务和通信挂钩,DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE这两个宏都定义在刚才的IInterface.h中:
在这里插入图片描述
??将IServiceManager的DELCARE宏进行相应的替换后得到的代码如下所示:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
??interface_cast是如何吧BpBinder指针转换成一个IServiceManager指针的?

intr = new BpServiceManager(obj);

??interface_cast不是指针的转换,而是利用BpBinder对象作为参数新建一个BpServiceManager对象。

IServiceManager家族
在这里插入图片描述
??1.IServiceManager、BpServiceManager和BnServiceManger都与业务逻辑相关
??2.BnServiceManager同时从IServiceMangager派生,表示它可以直接参与Binder通信
??3.BpServiceManager虽然从BpInterface中派生,但是这条分支似乎与BpBinder没有关系
??4.BnServiceManager是一个虚类,它的业务函数最终需要子类来实现
??5.ServiceManager并没有使用错综复杂的派生关系,它直接打开Binder设别并与之交互

??BpServiceManager既不像它的兄弟BnServiceManager那样与Binder有直接血缘关系,那么怎么和Binder交互?
??BpRefBase中mRemote值就是BpBinder,BpServiceManager左边派生分支树上的一些列代码,它们都是在IService Manager.cpp中:
在这里插入图片描述
??BpInterface的实现代码如下:
在这里插入图片描述
??BpRefBase()的实现代码如下:
在这里插入图片描述
??可以看出是BpServiceMangager的一个变量mRemote指向了BpBinder,回想defaultServiceManger函数,可以得到两个关键对象:
??1.有一个BpBinder对象,它的handle值是0
??2.有一个BpServiceManager对象,它的mRemote值是BpBinder
??BpServiceManager对象实现了IServiceManager的业务函数,现在又有BpBinder作为通信的代表,下面要分析MediaPlayerService的注册过程,进一步分析业务函数的内部是怎么工作的。

2.4 注册MediaPlayerService

在这里插入图片描述
1.业务层的工作
??回到main函数,下一个要分析的是MediaPlayerService,代码如下:
在这里插入图片描述
??根据前面的分析可知,defaultServiceManager()实际返回的对象是BpServiceManager,它是IServiceManager的后代
在这里插入图片描述
??BpServiceManager的addService就是把请求数据打包成data后,传递给BpBinder的transact函数,交给通信层去处理。

2.通信层的工作
??BpBinder和Binder的方式在transact函数中
在这里插入图片描述
??在这个里面真正干活的是IPCThreadState,IPCThreadState的实现代码在IPCThreadState.cpp中
在这里插入图片描述
??构造函数IPCThreadState()
在这里插入图片描述
??每个线程都有一个IPCThreadState,每个IPCThreadState中都有一个mIn、一个mOut,其中,mIn是用来接收自Binder设备的数据的,而mOut则是用来存储发往Binder设备的数据的。

transact
??BpBinder的transact调用的IPCThreadState的transact函数,这个函数实际完成了与Binder通信的工作:
在这里插入图片描述
??writeTransactionData函数
在这里插入图片描述
在这里插入图片描述
??waitForResponse函数
在这里插入图片描述
在这里插入图片描述
??回复的处理函数executeCommand
在这里插入图片描述
在这里插入图片描述
??和binder设备的交互,talkwithDriver函数
在这里插入图片描述
在这里插入图片描述

2.5 StartThread Pool和join Thread Pool分析

??StartThreadPool()函数
在这里插入图片描述
??spawnPooledThread()函数
在这里插入图片描述
??PoolThread是在IPCThreadState中定义的一个Thread子类:
在这里插入图片描述
??joinThreadPool函数的实现:
在这里插入图片描述
??到底有多少线程在为Service服务?目前是两个
??1.startThreadPool中新启动的线程通过joinThreadPool读取binder设备,查看是否有请求
??2.主线程调用joinThreadPool读取binder设备,查看是否有请求,binder设备时支持多线程操作的,其中一定时做了同步方面的工作

??我们以MediaServer为例,分析了Binder的机制,这里还是有必要再次强调一下Binder通信和基于Binder通信的业务之间的关系
??1.Binder是通信机制
??2.业务可以基于Binder通信也可使用别的IPC方式通信
Binder之所以复杂,重要原因之一在于Android通过层层封装,巧妙的把通信和业务融合在一起。
在这里插入图片描述

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-23 10:58:30  更:2022-04-23 10:58:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 23:34:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码