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

相关推荐
毕设源码-朱学姐14 分钟前
【开题答辩全过程】以 基于Android的便民系统的设计与实现为例,包含答辩的问题和答案
android
鬼蛟24 分钟前
Spring————事务
android·java·spring
qq_170264752 小时前
unity出安卓年龄分级的arr包问题
android·unity·游戏引擎
kejiashao4 小时前
Android View的绘制流程及事件分发机制
android
小蜜蜂嗡嗡4 小时前
flutter实现付费解锁内容的遮挡
android·flutter
进击的cc4 小时前
拒绝背诵!一文带你打穿 Android ANR 发生的底层全链路
android·面试
进击的cc4 小时前
App 启动优化全家桶:别再只盯着 Application 了,热启动优化你真的做对了吗?
android·面试
彭波3965 小时前
安卓手机端安装xapk、apkm软件!怎样安装xapk软件?安卓的apk和XAPK的区别?附教程
android·智能手机
Yang-Never6 小时前
ADB ->adb shell perfetto 抓取 trace 指令
android·开发语言·adb·android studio
2501_937189238 小时前
莫凡电视:地方台专属聚合 稳定直播播放工具
android·源码·源代码管理