Android 应用工程师的 Binder 原理剖析(五)进程间通信之bindService流程

ServiceManager在init进程启动之后启动,用来管理系统中的service注册、查找、通讯等。

1、注册:首先会检查是否有权限注册service,如果没有权限就直接返回不能注册;然后去检查该service是否已经注册过了,如果已经注册过,那就不能再注册;再判断内存是否够用。如果都没有问题,就会注册该service,加入到svcList中来,(在servicemanager中维护service信息的地方就是svcList,里面存了service的name和handler)。

2、查找:通过name从svcList找到对应等service,返回对应的handler

3、通讯:ServiceManager以类似Loop的工作方式不断从Binder设备中读取消息,发送给对应的service;若没有消息,则会进入等待状态,等待新消息到来再被激活;由于每个App只能打开一次Binder设备,做一次内存映射,所有需要使用binder驱动的线程共享这一资源,即共享同一个ServiceManager。

ServiceManager的启动

所有的系统服务都是需要在ServiceManager中进行注册的,而ServiceManager作为一个起始的服务,是通过init.rc来启动的。

arduino 复制代码
//system\core\rootdir\init.rc
//启动的服务,这里是用的服务名称。服务名称是在对应的rc文件中注册并启动的
start servicemanager

具体的服务信息是在servicemanger.rc命名并定义的

kotlin 复制代码
//\frameworks\native\cmds\servicemanager\servicemanager.rc
service servicemanager /system/bin/servicemanager
  class core animation
  user system //说明以用户system身份运行
  group system readproc
  //说明servicemanager是系统中的关键服务,
  //关键服务是不会退出的,如果退出了,系统就会重启,当系统重启时就会启动用onrestart关键字修饰的进程,
  //比如zygote、media、surfaceflinger等等。
  critical
  onrestart restart healthd
  onrestart restart zygote
  onrestart restart audioserver
  onrestart restart media
  onrestart restart surfaceflinger
  onrestart restart inputflinger
  onrestart restart drm
  onrestart restart cameraserver
  onrestart restart keystore
  onrestart restart gatekeeperd
  onrestart restart thermalservice
  ..

servicemanager的入口函数在frameworks\native\cmds\servicemanager\main.cpp中

代码如下:

rust 复制代码
int main(int argc, char** argv) {
//根据上面的rc文件,argc == 1, argv[0] == "/system/bin/servicemanager"
   if (argc > 2) {
       LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
  }
//此时,要使用的binder驱动为/dev/binder
   const char* driver = argc == 2 ? argv[1] : "/dev/binder";

//初始化binder驱动
   sp<ProcessState> ps = ProcessState::initWithDriver(driver);
   ps->setThreadPoolMaxThreadCount(0);
   ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);

//实例化ServiceManager
   sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
   //将自身作为服务添加
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
       LOG(ERROR) << "Could not self register servicemanager";
  }
   //设置服务端Bbinder对象
   IPCThreadState::self()->setTheContextObject(manager);
//设置成为binder驱动的context manager,成为上下文的管理者
   ps->becomeContextManager(nullptr, nullptr);

//通过Looper epoll机制处理binder事务
   sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);

   BinderCallback::setupTo(looper);
   ClientCallbackCallback::setupTo(looper, manager);

   while(true) {
       looper->pollAll(-1);
  }

   // should not be reached
   return EXIT_FAILURE;
}

具体的逻辑整理成长下面的流程图:

如上图,启动流程的变动主要在进入循环的方式,Android 11 之前是通过binder_loop方法,而现在是通过 looper。

和原来的 servicemanager 服务相比较,使用了 libbinder 后,代码更规范化,和其他 native 的服务风格一致了。

1)之前是直接 open、mmap 现在是借助 libbinder

2)之前是 binder_loop死 循环接收驱动的消息,现在是通过 looper 监听 fd 来handleEvent

3)之前的鉴权现在被独立到单独文件 Access.cpp

今日分享到此结束,对你有帮助的话,点个赞再走呗,如遇侵权联系删除
关注公众号:Android老皮

解锁 《Android十大板块文档》 ,让学习更贴近未来实战。已形成PDF版

内容如下

1.Android车载应用开发系统学习指南(附项目实战)
2.Android Framework学习指南,助力成为系统级开发高手
3.2023最新Android中高级面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨平台首要之选
7.Kotlin从入门到实战,全方面提升架构基础
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 性能优化实战+360°全方面性能调优
10.Android零基础入门到精通,高手进阶之路

相关推荐
试行27 分钟前
Android实现自定义下拉列表绑定数据
android·java
Dingdangr5 小时前
Android中的Intent的作用
android
技术无疆5 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
GEEKVIP5 小时前
Android 恢复挑战和解决方案:如何从 Android 设备恢复删除的文件
android·笔记·安全·macos·智能手机·电脑·笔记本电脑
Jouzzy12 小时前
【Android安全】Ubuntu 16.04安装GDB和GEF
android·ubuntu·gdb
极客先躯13 小时前
java和kotlin 可以同时运行吗
android·java·开发语言·kotlin·同时运行
Good_tea_h15 小时前
Android中的单例模式
android·单例模式
计算机源码社20 小时前
分享一个基于微信小程序的居家养老服务小程序 养老服务预约安卓app uniapp(源码、调试、LW、开题、PPT)
android·微信小程序·uni-app·毕业设计项目·毕业设计源码·计算机课程设计·计算机毕业设计开题
丶白泽21 小时前
重修设计模式-结构型-门面模式
android
晨春计1 天前
【git】
android·linux·git