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零基础入门到精通,高手进阶之路

相关推荐
C4rpeDime1 小时前
自建MD5解密平台-续
android
鲤籽鲲3 小时前
C# Random 随机数 全面解析
android·java·c#
m0_548514776 小时前
2024.12.10——攻防世界Web_php_include
android·前端·php
凤邪摩羯7 小时前
Android-性能优化-03-启动优化-启动耗时
android
凤邪摩羯7 小时前
Android-性能优化-02-内存优化-LeakCanary原理解析
android
喀什酱豆腐7 小时前
Handle
android
m0_748232929 小时前
Android Https和WebView
android·网络协议·https
m0_748251729 小时前
Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)
android·游戏·unity
m0_7482546611 小时前
go官方日志库带色彩格式化
android·开发语言·golang
zhangphil11 小时前
Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现“刮刮乐”效果,Kotlin(2)
android·kotlin