news 2026/8/4 3:09:12

Android 15 ServiceManager与Binder服务注册深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android 15 ServiceManager与Binder服务注册深度解析

引言

在上一篇文章中,我们深入分析了Binder驱动的内核机制。但是有一个核心问题还没有回答:Client如何知道Server的Binder句柄?

想象一下,你想打电话给朋友,但你不知道他的电话号码。这时你需要查电话簿(Yellow Pages)。在Android系统中,ServiceManager就是这本"电话簿"——它维护了系统中所有服务的注册表,提供服务的注册和查询功能。

没有ServiceManager,Binder IPC就无法工作。所有的系统服务(如ActivityManagerService、WindowManagerService)都需要先向ServiceManager注册,客户端才能通过ServiceManager查询到它们的Binder句柄,进而进行跨进程调用。

本文将深入Android 15源码,剖析ServiceManager的工作机制:

你将学到:

  • ServiceManager的启动流程与特殊性
  • 服务注册(addService)的完整实现
  • 服务查询(getService)的查找机制
  • 死亡通知(DeathRecipient)的工作原理
  • VINTF声明验证与安全机制
  • Android 15的新特性与优化

ServiceManager的特殊性

在深入代码前,我们先理解ServiceManager的几个特殊之处。

1. Handle 0:ServiceManager的唯一标识

在Binder系统中,ServiceManager有一个硬编码的句柄值:0

// ProcessState.cppenum{CONTEXT_MGR_HANDLE=0// ServiceManager的句柄固定为0};

这是一个"先有鸡还是先有蛋"的问题:

  • 所有服务都需要向ServiceManager注册
  • 但客户端如何获取ServiceManager的句柄?

解决方案:将ServiceManager的句柄硬编码为0。这样,所有进程都知道,要与ServiceManager通信,只需要使用handle=0。

💡设计巧思: Handle 0是Binder协议的特殊约定,在Binder驱动初始化时就预留了这个位置给ServiceManager。这是一个优雅的引导机制(Bootstrap)。

2. Context Manager:成为Binder上下文管理者

ServiceManager不仅仅是一个普通服务,它还是Binder上下文管理者(Context Manager)

// main.cpp (Android 15)intmain(intargc,char**argv){constchar*driver=argc==2?argv[1]:"/dev/binder";sp<ProcessState>ps=ProcessState::initWithDriver(driver);sp<ServiceManager>manager=sp<ServiceManager>::make(std::make_unique<Access>());// 关键步骤1:将自己设置为Context ObjectIPCThreadState::self()->setTheContextObject(manager);// 关键步骤2:向驱动注册为Context Managerif(!ps->becomeContextManager()){LOG(FATAL)<<"Could not become context manager";}// 进入消息循环sp<Looper>looper=Looper::prepare(false);while(true){looper->pollAll(-1);}}

becomeContextManager做了什么?

// ProcessState.cppboolProcessState::becomeContextManager(){// 通过ioctl告诉驱动:"我是ServiceManager"flat_binder_object obj{.flags=FLAT_BINDER_FLAG_ACCEPTS_FDS,};binder_write_read bwr{};binder_transaction_data tr{};tr.target.handle=0;tr.code=BINDER_SET_CONTEXT_MGR;// 驱动会将handle 0绑定到当前进程intresult=ioctl(mDriverFD,BINDER_WRITE_READ,&bwr);returnresult==0;}

驱动收到BINDER_SET_CONTEXT_MGR命令后,会:

  1. 检查调用进程是否有权限(需要root或system权限)
  2. 将handle 0永久绑定到ServiceManager进程
  3. 确保只有一个进程能成为Context Manager

3. 单例且唯一

整个Android系统中,只能有一个ServiceManager实例。它由init进程在系统启动早期启动,并一直运行直到系统关闭。

# init.rc中的ServiceManager启动配置serviceservicemanager /system/bin/servicemanager class core animation user system group system readproc critical onrestart restart apexd onrestart restart audioserver# ...重启时需要重启依赖的服务

critical标志:ServiceManager被标记为关键服务,如果它崩溃,系统会自动重启进入恢复模式。

ServiceManager架构概览

在深入启动流程前,先看看ServiceManager的整体架构:

图1: ServiceManager架构 - SystemServer注册服务,Client查询服务,ServiceManager维护服务注册表

ServiceManager启动流程

让我们跟踪ServiceManager从启动到就绪的完整流程。

1. main函数:初始化与准备

// main.cpp (Android 15)intmain(intargc,char**argv){// 1. 初始化日志android::base::InitLogging(argv,android::base::KernelLogger);constchar*driver=argc==2?argv[1]:"/dev/binder";#if!defined(VENDORSERVICEMANAGER)android::register_perfetto_te_categories();// Perfetto追踪#endifLOG(INFO)<<"Starting sm instance on "<<driver;// 2. 初始化ProcessStatesp<ProcessState>ps=ProcessState::initWithDriver(driver);ps->setThreadPoolMaxThreadCount(0);// 不使用线程池,单线程处理ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);// 3. 禁用后台调度,确保高优先级IPCThreadState::self()->disableBackgroundScheduling(true);// 4. 创建ServiceManager实例sp<ServiceManager>manager=sp<ServiceManager>::make(std::make_unique<Access>());// 5. 自己也要注册为服务(服务的服务)if(!manager->addService("manager",manager,false/*allowIsolated*/,IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()){LOG(ERROR)<<"Could not self register servicemanager";}// 6. 成为Context ManagerIPCThreadState::self()->setTheContextObject(manager);if(!ps->becomeContextManager()){LOG(FATAL)<<"Could not become context manager";}// 7. 设置事件循环sp<Looper>looper=Looper::prepare(false);sp<BinderCallback>binderCallback=BinderCallback::setupTo(looper);ClientCallbackCallback::setupTo(looper,manager,binderCallback);// 8. 设置ready属性,通知其他进程可以使用了#ifndefVENDORSERVICEMANAGERif(!SetProperty("servicemanager.ready","true")){LOG(ERROR)<<"Failed to set servicemanager ready property";}#endif// 9. 进入消息循环,永不退出while(true){looper->pollAll(-1);// 阻塞等待Binder事务}returnEXIT_FAILURE;// 不应该到达这里}

关键点解析:

  1. 单线程模式:setThreadPoolMaxThreadCount(0)表示不使用Binder线程池,只用主线程处理,简化并发控制
  2. 只接受单向调用:FATAL_IF_NOT_ONEWAY确保所有对ServiceManager的调用都是异步的,防止死锁
  3. 高优先级:disableBackgroundScheduling(true)确保ServiceManager不会被降优先级
  4. 自我注册:ServiceManager也将自己注册为名为"manager"的服务,供特殊情况使用
  5. Ready属性:通过系统属性通知其他等待的进程

2. Looper事件循环

ServiceManager使用Looper而不是传统的Binder线程池:

// BinderCallback:处理Binder事件classBinderCallback:publicLooperCallback{public:staticsp<BinderCallback>setupTo(constsp<Looper>&looper){sp<BinderCallback>cb=sp<BinderCallback>::make
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/31 10:27:44

【毕业设计】java-springboot+vue“智慧食堂”设计与实现

&#x1f49f;博主&#xff1a;程序员陈辰&#xff1a;CSDN作者、博客专家、全栈领域优质创作者 &#x1f49f;专注于计算机毕业设计&#xff0c;大数据、深度学习、Java、小程序、python、安卓等技术领域 &#x1f4f2;文章末尾获取源码数据库 &#x1f308;还有大家在毕设选题…

作者头像 李华
网站建设 2026/8/1 12:18:54

奇点之后:Omega+级量子AI的世界

版权声明:本文为DREAMVFIA UNION原创作品,2026年版权所有。未经授权,禁止转载、摘编或以任何形式传播本文内容。 摘要 当人类文明的技术发展曲线趋向无穷大时,我们正站在一个前所未有的历史转折点。技术奇点——那个理论物理学家约翰冯诺依曼首次预言、人工智能先驱维诺尔…

作者头像 李华
网站建设 2026/8/3 10:28:28

安装了多个版本VS导致无法安装vsix

博主先后安装了VS2015和VS2019&#xff0c;在给VS2015安装qt-vsaddin插件时运行vsix报错&#xff0c;‘View Install Log’有显示&#xff0c;后续给出了在cmd运行的解决办法。 如&#xff0c;先后安装了VS2015、VS2019&#xff0c;现在想给VS2015安装一个qt-vsaddin插件&#…

作者头像 李华
网站建设 2026/7/31 5:46:21

CVE-2025-55752 Tomcat 路径绕过与漏洞检测工具详解

CVE-2025-55752 Tomcat 路径绕过与漏洞检测工具 项目描述 本工具是一个专门用于检测和验证 Apache Tomcat 服务器是否存在 CVE-2025-55752 漏洞的安全脚本。该漏洞是由于重写阀门&#xff08;Rewrite Valve&#xff09;与规范化处理存在缺陷&#xff0c;导致攻击者可以绕过路径…

作者头像 李华
网站建设 2026/7/17 9:39:19

导师又让重写?千笔,专科生论文写作救星!

你是否在论文写作中感到力不从心&#xff1f;选题无头绪、资料难查找、结构混乱、查重率高得让人焦虑……这些困扰让无数专科生在毕业季倍感压力。面对导师的反复修改要求&#xff0c;你是否也曾感到无助&#xff1f;别再独自挣扎&#xff0c;千笔AI正是为解决这些问题而生。它…

作者头像 李华
网站建设 2026/7/31 5:24:50

FLAC3D水力压裂实例解析:单孔与双孔的奇妙世界

FLAC3D水力压裂例子&#xff0c;可以拿来参考&#xff0c;有单孔和双孔。在岩土工程和石油工程等领域&#xff0c;水力压裂是一项至关重要的技术&#xff0c;它通过向地下岩石注入高压流体&#xff0c;使岩石产生裂缝&#xff0c;从而提高油气的开采效率。FLAC3D作为一款强大的…

作者头像 李华