ServiceManager在init进程启动之后启动,用来管理系统中的service,那么首先理解一下在init进程启动之后启动这句话类:

一般开机过程分为三个阶段:

  1. OS级别,由bootloader载入linux内核后,内核开始初始化,并载入built-in的驱动程序,内核完成开机后,载入init process,切换至user-space后,结束内核的循序过程,进入排成模式。
  2. Android-level,由init process开始,读取init.rc,Mative服务启动,并启动重要的外部程序,例如servicemanager、zygote以及system service。
  3. Zygote-Mode,Zygote启动完System Service后,进入Zygote Mode,在Socket等候命令,随后,使用者将看到一个桌面环境,桌面环境由一个名为Launcher的应用程序负责提供。

在ServiceManager中有两个比较重要的方法:add_service和check_service,系统的service需要通过add_service把自己的信息注册到servicemanager中,当需要使用时,通过check_service检查该service是否存在。看它的main函数的源码:

三件事:

  1. 打开Binder设备,并在内存中映射128k的空间

首先看一下struct binder_state这个结构体

struct binder_state{
int fd; //文件描述符,打开/dev/binder设备
void* mapped; //把设备文件/dev/binder映射到进程空间的起始地址
unsigned mapsize; //映射内存空间的大小
}
  1. 告诉Binder驱动程序,自己是Binder上下文管理者

  2. 进入循环,不停去读Binder设备,看是否有对service的请求,如果有的话就去调用svcmgr_handller函数回调处理请求。

下面就来看一下servicemanager是怎么循环等待客户端的请求,并进行注册服务、服务获取这一系列活动的。

等待客户端请求

ServiceManager进程通过binder_loop方法进入循环等待客户端的请求中,当有客户端请求时,进程ServiceManager被唤醒并调用svcmgr_handler来处理客户端的请求。

  1. ServiceManager进程在进入循环前,调用binder_write()方法,通过ioctl系统调用设置Binder线程的运行状态为BINDER_LOOPER_STATE_ENTERED,看下binder_write()方法的源码:

首先设置binder_write_read结构体变量的值,然后通过ioctl传递到Binder驱动程序中,此时控制命令为BINDER_WRITE_READ,binder_ioctl函数中对BINDER_WRITE_READ命令的处理过程为:

在binder_thread_write方法中,对BC_ENTER_LOOPER Binder协议的处理如下:

此处仅仅设置了binder_thread结构体变量中的线程运行状态looper为BINDER_LOOPER_STATE_ENTERED,表示当前的binder线程进入循环状态。

2. 睡眠等待客户端请求

在没有客户端请求时,当前进程就进入休眠状态,等待请求到来再唤醒。

总结一哈?

ServiceManager进程的启动首先打开binder驱动并开辟内核缓存区,同时将缓存区的物理页面同时映射到内核虚拟地址空间及进程虚拟地址空间中,然后在内核中创建属于servicemanager进程的binder_node实体节点,接着设置处理客户端请求的binder线程运行状态,由于此时没有客户端的请求,servicemanager进程进入睡眠等待中,直到客户端请求的到来时,唤醒servicemanager进程,再继续往下执行。

服务注册

直接来看,当有service请求时,调用的回到函数svcmgr_handler函数。

如果请求注册,就执行红色框中的代码,我们再来看一下具体实现do_add_service()方法是怎么实现的:

看代码中的三个红框,首先会检查是否有权限注册service,如果没有权限就直接返回不能注册;然后去检查该service是否已经注册过了,如果已经注册过,那就不能再注册;再判断内存是否够用。如果都没有问题,就会注册该service,加入到svcList中来,(在servicemanager中维护service信息的地方就是svcList,里面存了service的name和handler)。通过以上几步,service就算注册成功了。

服务获取

如果是服务获取,就会执行代码中的黄色框,并将返回的数据写入reply,返回给客户端,do_find_service函数中主要执行service的查找,看源码:

Android-ServiceManager的更多相关文章

  1. Android ServiceManager启动

    许久就想写篇关于servicemanager的文章,之前对服务启动顺序诸如zygote,systemserver.等启动顺序理解有点混乱,现做例如以下理解分析: 事实上init进程启动后,Servic ...

  2. ServiceManager: Permmission failure: android.permission.RECORD_AUDIO

    今天在Android6.0系统的手机上测试一款APP,出现如题错误: ServiceManager: Permmission failure: android.permission.RECORD_AU ...

  3. [置顶] Android开发之serviceManager分析

    Android 开发之serviceManager分析 在Android系统中用到最多的通信机制就是Binder,Binder主要由Client.Server.ServiceManager和Binde ...

  4. Android 之 ServiceManager与服务管理

    ServiceMananger是android中比较重要的一个进程,它是在init进程启动之后启动,从名字上就可以看出来它是用来管理系统中的service.比如:InputMethodService. ...

  5. [转]Android Binder设计与实现 - 设计篇

    摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder ...

  6. Android来电监听和去电监听

    我觉得写文章就得写得有用一些的,必须要有自己的思想,关于来电去电监听将按照下面三个问题展开 1.监听来电去电有什么用? 2.怎么监听,来电去电监听方式一样吗? 3.实战,有什么需要特别注意地方? 监听 ...

  7. [Android Studio]SQLScout插件安装破解

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5972138.html [Android Studio]SQLS ...

  8. Android应用架构之Android MVP使用

    前两篇已经将Retrofit和RxAndroid应用到了项目中,这篇本打算直接将Dagger2引进项目,但是考虑到整个项目结构,就来个结构整理吧,一起来看看网上炒得火热MVP模式. 说到MVP就不得不 ...

  9. Android系统全貌 (转)

    转自Gityuan的Android开篇,对自我学习作进一步整理. Android系统以Linux内核作为基底,上层采用Native层和Java层.系统分为内核空间和用户空间,并通过系统调用(Sysca ...

  10. android开发读书笔记

    第九章心得: HAL ( Hardware Abstraction Layer,硬件抽象腔,〉是建立在Linux驱动之上的一套翻字库.这套程序 j率并不属于 Linux 内核, 而是属于 Linux ...

随机推荐

  1. 玩转Django2.0---Django笔记建站基础十二(Django项目上线部署)

    第十二章 Django项目上线部署 目前部署Django项目有两种主流方案:Nginx+uWsGI+Django或者Apache+uWSGI+Django.Nginx作为服务器最前端,负责接收浏览器的 ...

  2. Bate冲刺博客(3次)

    Bate冲刺博客 课程介绍 课程 (https://edu.cnblogs.com/campus/xnsy/GeographicInformationScience) 作业要求 https://www ...

  3. xpath写法汇总(适用于appium、robotframework)

    1.移动端应用,content-des包含“订单号” xpath=//android.view.View[contains(@content-desc,"订单号:")] 2.移动端 ...

  4. jmeter使用—计数器的使用

    说一下jmeter中,配置元件-计数器的使用. 如果需要引用的数据量较大,且要求不能重复或者需要自增,那么可以使用计数器来实现. 1.启动jmeter,添加线程组,右键添加配置元件——计数器,如下图: ...

  5. idea搭建springmvc(maven版)

    一.创建maven项目 (1)选择 file > new > project (2)填写对应信息,一路点击next 配置自己本地的maven,继续next 命名项目名(随意写,但要易懂), ...

  6. LeetCode题目总结-滑窗法

    LeetCode题目总结-滑动窗口法 滑动窗口法:此方法首先建立一个长度为零的窗口,把右侧窗口向右移动,当新的元素与原来窗口中的元素不重复时,把新的元素加入其中,并更新窗口长度:当新的元素与原集合中的 ...

  7. docker启动redis端口映射错误问题解决

    今天使用docker安装redis,使用的时候出现了一些问题.第一次安装好后,在虚拟机后台启动了redis,然后在连接虚拟机的redis的时候怎么也连不上.出现这种情况我第一反应是防火墙没有开启所以我 ...

  8. 小米重新上锁[BL]

    解锁一时爽,bug火葬场.废话不多说,直接上教程. 首先安装 线刷工具:http://bigota.d.miui.com/tools/MiFlash2018-5-28-0.zip 解锁工具:http: ...

  9. 看片微信号+薇myy9199买片微信号+myy9199绝对靠谱号

    最新看片卖片微信号+myy9199,2020最新有效靠谱号,诚信有效,死链包换,2019年11月,我决定学习计算机编程,以java语言为主.我就读于传统工科专业,没怎么接触过计算机相关概念与课程,我知 ...

  10. printf的用法进阶

    今天来好好总结一下C语言中关于printf的常用用法 基础部分 printf("%d\n", numInt); printf("%f\n", numFloat) ...