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. 什么是“跑面”呢? - ERSS耳斯百科:您的随身移动百科

    跑面 [pǎo miàn] 跑面,是一个汉语词汇,拼音为pǎo miàn,英文名为Run-Noodles,最基本解释为人跑步去吃面,其意义还有多重深层解释. 中文名:跑面 英文名:Run-Noodle ...

  2. Git提交代码和更新代码命令

    微信公众号:非科班的科班关注可了解更多的java教程和其它资源视频.问题或建议,请公众号留言; 1.Git提交代码 利用命令提交代码的步骤:1.1.拉取服务器代码,避免覆盖他人的代码 git pull ...

  3. Linux系统实时数据同步inotify+rsync

    一.inotify简介 inotify是Linux内核的一个功能,它能监控文件系统的变化,比如删除.读.写和卸载等操作.它监控到这些事件的发生后会默认往标准输出打印事件信息.要使用inotify,Li ...

  4. 本地Linux虚拟机内网穿透,服务器文件下载到本地磁盘

    本地Linux虚拟内网穿透 把服务器文件下载到本地磁盘 https://natapp.cn/ 1.注册账户点击免费隧道  

  5. Git详解之分支使用

    前言 几乎每一种版本控制系统都以某种形式支持分支.使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作.在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的完整副本 ...

  6. C语言系列之自增自减运算符的用法(二)

    运算符中最难理解的有自增自减运算符的使用方法,下面我将简单总结一下他们的使用方法 我们知道,C语言运行是由右向左运行的 下面我们来看一个例子 当i等于3的时候 j=++i; 由上面可知,C语言是由右向 ...

  7. pycharm破解码

    今天又遇到了pycharm注册码失效的问题: 找到了一个好用的破解教程,为了能够尽快的使用,我用的是注册码的方式 教程链接:https://www.cnblogs.com/yuuje/p/101009 ...

  8. 搭建DevOps模式的项目

    在后端的开发领域,各类开发框架都已经很多,在开发项目时可以根据不同的需要和需求选择合适的开发框架.然而在需要开发一个完善的工程化项目时,仅仅一个后端开发框架是不够的,还面临着在对开发项目的快速迭代中进 ...

  9. redis 常用命令行

    一.key 相关: ()redis允许模糊查询 key(keys *) 有3个通配符 *.?.[] ()randomkey:返回随机key ()type key:返回key存储的类型 ()exists ...

  10. 使用alpine制作最小化的JDK基础镜像

    注意:这里使用的是oracle的JRE,版本是1.8. 1.解压jre包,删除根目录下文本文件,然后删除其他不必要文件. #解压 tar xvcf jre-8u161-linux-x64.tar.gz ...