Android Binder中的Server和Client获得Service Manager接口

Unity安卓打包实战:SDK与JDK配置全攻略 本文详细介绍了Unity安卓打包过程中SDK与JDK的配置方法,包括工具下载、安装步骤、环境变量设置及常见错误排查。通过实战指南帮助开发者快速完成Unity安卓打包环境搭建,提升开发效率。 阅读详情
文章 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路 中,介绍了Service Manager是如何成为Binder机制的守护进程的。既然作为守护进程,Service Manager的职责当然就是为Server和Client服务了。那么,Server和Client如何获得Service Manager接口,进而享受它提供的服务呢?本文将简要分析Server和Client获得Service Manager的过程。

        在阅读本文之前,希望读者先阅读Android进程间通信(IPC)机制Binder简要介绍和学习计划一文提到的参考资料Android深入浅出之Binder机制,这样可以加深对本文的理解。

        我们知道,Service Manager在Binder机制中既充当守护进程的角色,同时它也充当着Server角色,然而它又与一般的Server不一样。对于普通的Server来说,Client如果想要获得Server的远程接口,那么必须通过Service Manager远程接口提供的getService接口来获得,这本身就是一个使用Binder机制来进行进程间通信的过程。而对于Service Manager这个Server来说,Client如果想要获得Service Manager远程接口,却不必通过进程间通信机制来获得,因为Service Manager远程接口是一个特殊的Binder引用,它的引用句柄一定是0。

        获取Service Manager远程接口的函数是defaultServiceManager,这个函数声明在frameworks/base/include/binder/IServiceManager.h文件中:

[cpp]  view plain copy
  1. sp<IServiceManager> defaultServiceManager();  

       实现在frameworks/base/libs/binder/IServiceManager.cpp文件中:

[cpp]  view plain copy
  1. sp<IServiceManager> defaultServiceManager()  
  2. {  
  3.   
  4.     if (gDefaultServiceManager != NULL) return gDefaultServiceManager;  
  5.   
  6.     {  
  7.         AutoMutex _l(gDefaultServiceManagerLock);  
  8.         if (gDefaultServiceManager == NULL) {  
  9.             gDefaultServiceManager = interface_cast<IServiceManager>(  
  10.                 ProcessState::self()->getContextObject(NULL));  
  11.         }  
  12.     }  
  13.   
  14.     return gDefaultServiceManager;  
  15. }  
        gDefaultServiceManagerLock和gDefaultServiceManager是全局变量,定义在frameworks/base/libs/binder/Static.cpp文件中:

[cpp]  view plain copy
  1. Mutex gDefaultServiceManagerLock;  
  2. sp<IServiceManager> gDefaultServiceManager;  
        从这个函数可以看出,gDefaultServiceManager是单例模式,调用defaultServiceManager函数时,如果gDefaultServiceManager已经创建,则直接返回,否则通过interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))来创建一个,并保存在gDefaultServiceManager全局变量中。

       在继续介绍interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))的实现之前,先来看一个类图,这能够帮助我们了解Service Manager远程接口的创建过程。


        参考资料Android深入浅出之Binder机制一文的读者,应该会比较容易理解这个图。这个图表明了,BpServiceManager类继承了BpInterface<IServiceManager>类,BpInterface是一个模板类,它定义在frameworks/base/include/binder/IInterface.h文件中:

[cpp]  view plain copy
  1. template<typename INTERFACE>  
  2. class BpInterface : public INTERFACE, public BpRefBase  
  3. {  
  4. public:  
  5.     BpInterface(const sp<IBinder>& remote);  
  6.   
  7. protected:  
  8.     virtual IBinder* onAsBinder();  
  9. };  
        IServiceManager类继承了IInterface类,而IInterface类和BpRefBase类又分别继承了RefBase类。在BpRefBase类中,有一个成员变量mRemote,它的类型是IBinder*,实现类为BpBinder,它表示一个Binder引用,引用句柄值保存在BpBinder类的mHandle成员变量中。BpBinder类通过IPCThreadState类来和Binder驱动程序并互,而IPCThreadState又通过它的成员变量mProcess来打开/dev/binder设备文件,mProcess成员变量的类型为ProcessState。ProcessState类打开设备/dev/binder之后,将打开文件描述符保存在mDriverFD成员变量中,以供后续使用。

        理解了这些概念之后,就可以继续分析创建Service Manager远程接口的过程了,最终目的是要创建一个BpServiceManager实例,并且返回它的IServiceManager接口。创建Service Manager远程接口主要是下面语句:

[cpp]  view plain copy
  1. gDefaultServiceManager = interface_cast<IServiceManager>(  
  2.     ProcessState::self()->getContextObject(NULL));  
        看起来简短,却暗藏玄机,具体可阅读 Android深入浅出之Binder机制 这篇参考资料,这里作简要描述。

        首先是调用ProcessState::self函数,self函数是ProcessState的静态成员函数,它的作用是返回一个全局唯一的ProcessState实例变量,就是单例模式了,这个变量名为gProcess。如果gProcess尚未创建,就会执行创建操作,在ProcessState的构造函数中,会通过open文件操作函数打开设备文件/dev/binder,并且返回来的设备文件描述符保存在成员变量mDriverFD中。

        接着调用gProcess->getContextObject函数来获得一个句柄值为0的Binder引用,即BpBinder了,于是创建Service Manager远程接口的语句可以简化为:

[cpp]  view plain copy
  1. gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));  
        再来看函数interface_cast<IServiceManager>的实现,它是一个模板函数,定义在framework/base/include/binder/IInterface.h文件中:

[cpp]  view plain copy
  1. template<typename INTERFACE>  
  2. inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)  
  3. {  
  4.     return INTERFACE::asInterface(obj);  
  5. }  
        这里的INTERFACE是IServiceManager,于是调用了IServiceManager::asInterface函数。IServiceManager::asInterface是通过DECLARE_META_INTERFACE(ServiceManager)宏在IServiceManager类中声明的,它位于framework/base/include/binder/IServiceManager.h文件中:

[cpp]  view plain copy
  1. DECLARE_META_INTERFACE(ServiceManager);  

        展开即为:

[cpp]  view plain copy
  1. #define DECLARE_META_INTERFACE(ServiceManager)                              \  
  2.     static const android::String16 descriptor;                          \  
  3.     static android::sp<IServiceManager> asInterface(                    \  
  4.     const android::sp<android::IBinder>& obj);                          \  
  5.     virtual const android::String16& getInterfaceDescriptor() const;    \  
  6.     IServiceManager();                                                  \  
  7.     virtual ~IServiceManager();                                           

       IServiceManager::asInterface的实现是通过IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")宏定义的,它位于framework/base/libs/binder/IServiceManager.cpp文件中:

[cpp]  view plain copy
  1. IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");  
       展开即为:

[cpp]  view plain copy
  1. #define IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")                 \  
  2.     const android::String16 IServiceManager::descriptor("android.os.IServiceManager");     \  
  3.     const android::String16&                                   \  
  4.     IServiceManager::getInterfaceDescriptor() const {                                      \  
  5.     return IServiceManager::descriptor;                                                    \  
  6.     }                                                                                      \  
  7.     android::sp<IServiceManager> IServiceManager::asInterface(                             \  
  8.     const android::sp<android::IBinder>& obj)                                              \  
  9.     {                                                                                      \  
  10.     android::sp<IServiceManager> intr;                                                     \  
  11.     if (obj != NULL) {                                                                     \  
  12.     intr = static_cast<IServiceManager*>(                                                  \  
  13.     obj->queryLocalInterface(                                                              \  
  14.     IServiceManager::descriptor).get());                                                   \  
  15.     if (intr == NULL) {                                                                    \  
  16.     intr = new BpServiceManager(obj);                                                      \  
  17.     }                                                                                      \  
  18.     }                                                                                      \  
  19.     return intr;                                                                           \  
  20.     }                                                                                      \  
  21.     IServiceManager::IServiceManager() { }                                                 \  
  22.     IServiceManager::~IServiceManager() { }        
         估计写这段代码的员工是从Microsoft跳槽到Google的。这里我们关注IServiceManager::asInterface的实现:

[cpp]  view plain copy
  1. android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)                                                
  2. {                                                                                       
  3.     android::sp<IServiceManager> intr;                                                      
  4.       
  5.     if (obj != NULL) {                                                                       
  6.         intr = static_cast<IServiceManager*>(                                                    
  7.                     obj->queryLocalInterface(IServiceManager::descriptor).get());  
  8.           
  9.         if (intr == NULL) {                  
  10.             intr = new BpServiceManager(obj);                                          
  11.         }                                            
  12.     }  
  13.     return intr;                                    
  14. }     
         这里传进来的参数obj就则刚才创建的new BpBinder(0)了,BpBinder类中的成员函数queryLocalInterface继承自基类IBinder,IBinder::queryLocalInterface函数位于framework/base/libs/binder/Binder.cpp文件中:

[cpp]  view plain copy
  1. sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)  
  2. {  
  3.     return NULL;  
  4. }  
         由此可见,在IServiceManager::asInterface函数中,最终会调用下面语句:

[cpp]  view plain copy
  1. intr = new BpServiceManager(obj);   
         即为:

[cpp]  view plain copy
  1. intr = new BpServiceManager(new BpBinder(0));   
        回到defaultServiceManager函数中,最终结果为:

[cpp]  view plain copy
  1. gDefaultServiceManager = new BpServiceManager(new BpBinder(0));  
        这样,Service Manager远程接口就创建完成了,它本质上是一个BpServiceManager,包含了一个句柄值为0的Binder引用。

        在Android系统的Binder机制中,Server和Client拿到这个Service Manager远程接口之后怎么用呢?

        对Server来说,就是调用IServiceManager::addService这个接口来和Binder驱动程序交互了,即调用BpServiceManager::addService 。而BpServiceManager::addService又会调用通过其基类BpRefBase的成员函数remote获得原先创建的BpBinder实例,接着调用BpBinder::transact成员函数。在BpBinder::transact函数中,又会调用IPCThreadState::transact成员函数,这里就是最终与Binder驱动程序交互的地方了。回忆一下前面的类图,IPCThreadState有一个PorcessState类型的成中变量mProcess,而mProcess有一个成员变量mDriverFD,它是设备文件/dev/binder的打开文件描述符,因此,IPCThreadState就相当于间接在拥有了设备文件/dev/binder的打开文件描述符,于是,便可以与Binder驱动程序交互了。

       对Client来说,就是调用IServiceManager::getService这个接口来和Binder驱动程序交互了。具体过程上述Server使用Service Manager的方法是一样的,这里就不再累述了。

CASS3D实战:高效三维房屋与地形采集绘制技巧 本文详细介绍了CASS3D在三维房屋与地形采集绘制中的高效技巧,包括智能绘房功能、不规则结构处理、特殊构件快速绘制及地形数据采集策略。通过实战案例和进阶操作指南,帮助用户快速掌握CASS3D的核心功能,提升三维采集与绘制效率。 阅读详情

相关推荐

当LightGBM推理遇上GPU:3种替代方案性能对比(含ONNX实战代码)

本文针对LightGBM官方不支持GPU推理的性能瓶颈,深度评测了RAPIDS cuML、ONNX Runtime GPU和Triton Inference Server三种GPU加速推理替代方案。通过详尽的性能对比和实战代码,为高并发、低延迟的在线预测场景提供了清晰的选型指南,帮助工程师打破推理性能枷锁,实现显著的吞吐量提升。

salt9的博客 812

浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路...

在前面一篇文章浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路中,介绍了Service Manager是如何成为Binder机制的守护进程的。既然作为守护进程,Service Manager的职责当然就是为Server和Client服务了。那么,Server和Client如何获得Service Manager接口,进而享受它提供的服务呢?本文将简...

oraclestudy 490

【chips】个人笔记系列-SystemVerilog

个人整理的Systemverilog笔记。

Hide_in_Code 2057

AIdl server端监听client是否掉线

我们知道当绑定service时 客户端可以收到服务端异常中断的消息 即onServiceConnected,那么服务器端是否可以监听到client端掉线的消息呢?下面就写个简单的demo用于监听client是否掉线 分三个moudle 分别是client server和AIDL模块 AIDL模块专门放AIDL文件 client server分别依赖AIDL模块 AIDL模块: IClientCallback // IClientCallback.aidl package com.example.common

积跬步 至千里 1809

ESP32对接百度智能云语音识别:从硬件配置到API调用的完整指南

本文详细介绍了ESP32对接百度智能云语音识别的完整流程,从硬件配置到API调用,涵盖麦克风选择、音频处理、错误处理及性能优化等关键环节。通过实战案例展示如何实现低成本、高效率的语音交互方案,特别适合智能硬件开发者参考。

weixin_29198045的博客 372

2023东华大学机试OJ进阶版1-81题

先排序。每次找两个最小的数,把其中一个置为两数之和,并累加这个和值,另一个数置为-1,然后再排序,重复操作,直到只剩下一个数。105。

m0_49263811的博客 2794

Binder系列6—获取服务(getService)

一、 获取服务在Native层的服务注册,我们选择以media为例来展开讲解,先来看看media的类关系图。1.1 类图点击查看大图图解:蓝色: 代表获取MediaPlayerService服务相关的类;绿色: 代表Binder架构中与Binder驱动通信过程中的最为核心的两个类;紫色: 代表注册服务和获取服务的公共接口/父类;二. 获取Media服务2.1 getMediaPlayerServi...

bob_fly1984的专栏 3246

Word毕业论文排版:图片和表格题注的终极指南(含自动编号技巧)

本文是Word毕业论文排版中图片和表格题注的终极指南,详细讲解了如何利用题注功能实现自动编号,告别繁琐易错的手动操作。核心内容包括创建定制标签、配置带章节的编号格式、插入交叉引用以及一键更新全文编号的技巧,旨在帮助学生构建自动化文档体系,提升排版效率和论文严谨性。

weixin_29211309的博客 1093

ServiceManager原理分析

参考: 系统服务管理者:ServiceManager进程

yzpbright的博客 818

在ubuntu20.04中安装MATLAB时常见问题及解决方法

   如果你刚装完ubuntu20.04,这时你想要安装MATLAB2021A,在输入命令./install进行安装时,可能会报以下错误:    terminate called after throwing an instance of ‘JailContainerException’ what(): Error: 88: No JRE version parsed from/media/jzx/MATHWORKS_R2021A/sys /java/jre/glnxa64/jre/release   

慕羽★的博客 1万+

多周期路径约束(set_multicycle_path )

1.由慢到快的多周期约束 如下图所示,发射时钟周期是接受时钟周期的4倍。默认情况下,按照1T原则来进行静态时序分析和布局布线的。即建立时间是在发射沿后的第一个捕获沿检查,而保持时间是同一时刻下源时钟和捕获时钟的触发边沿下检查的(建立时间检查边沿的前一个触发沿)。 但是这样导致的问题就是该路径过于苛刻,为了满足这条路径的要求,不得不放弃其他路径。或者根本没办法保证这个默认的约束。总之最终造成...

Arist. 5505

Android Binder通信原理(四):service获取

上一文中已经得知如何通过 defaultServiceManager() 得来的 BpInterface 与 servciemanager 进行通信,并分析了addServcie() 的流程,这里再来看下service 的获取过程。

私房菜 2742

【即插即用模块】注意力篇 | MICCAI 2023 | MFE:多尺度特征提取,告别固定感受野,猛涨2个点!

本文提出一种用于低分辨率乳腺癌病理图像超分辨率与分类的网络SHISRCNet。针对现有方法处理低分辨率图像效果差、感受野固定等问题,设计了多特征提取模块(MFE),通过多速率空洞卷积覆盖全尺度感受野(局部到全局),结合递进残差连接和动态权重融合机制,实现自适应多尺度特征增强。实验表明,该模块在超分辨率任务中PSNR提升近2个点,分类准确率显著提高。代码提供详细注释,支持即插即用,适用于各类多尺度视觉任务。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 206

浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路

在前面一篇文章浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路中,介绍了Service Manager是如何成为Binder机制的守护进程的。既然作为守护进程,Service Manager的职责当然就是为Server和Client服务了。那么,Server和Client如何获得Service Manager接口,进而享受它提供的服务呢?本文将简

老罗的Android之旅 10万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Android源码解析之Binder中Server和Client获得Service Manager接口

转载自:http://blog.youkuaiyun.com/luoshengyang/article/details/6627260 前一篇介绍了Service Manager是如何成为Binder机制的守护进程的。既然作为守护进程,Service Manager的职责当然就是为Server和Client服务了。那么,Server和Client如何获得Service Manager接口,进而享受它提供的服

Tomes.V.White 542

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

上一篇: Android Binder服务进程
下一篇: Android server启动过程源代码分析
计算机与认知
博客等级 码龄14年 31粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值