前言

众所皆知,Android系统是当前占据用户量最大的手机系统,国内流行的客户端开发无非是android 与 ios,即使作为一个普通用户,小伙伴们可曾想过这个给我们生活带来巨大变化的系统是如何为我们服务的呢?

Android系统可大致分为五层,如下图,第一层就是我们平时看到的各种应用了,这个小伙伴们肯定熟悉,这里就不多说了,要给大家介绍的是第二层——Framework,它直接对接应用程序,提供了本地系统服务和java系统服务。

那么这些服务是如何使用的呢,下面简要分析一下这个过程

Android Framework

先来看一个应用的启动过程

如上图,一个应用启动主要依赖于ActivityManager服务,它是系统提供的众多服务里的其中一个,服务作为framework提供的主要内容,扮演着承上启下的重要责任:一方面为应用提供约定好的功能调用接口,另一方面无需应用关心服务如何实现,framework会负责与底下驱动层进行交互,达到目的。

正因为有了framework层,应用开发才能事半功倍,专注于业务逻辑实现,接下来就来介绍一下服务如何运行.

1、服务检索

服务检索是指调用服务的客户端向Context Manager(service manager中第一个注册的节点)请求指定服务的handle的过程。调用服务的客户端把包含服务请求信息的IPC数据发送给Context Manager,然后Context Manager通过IPC应答数据将指定服务的handle发送给它。Binder Driver将把调用服务的客户端请求的服务的binder_node结构体注册到客户端的bind_proc结构体中。

针对上面这段话有三点需要解释一下:

1)service_manager如何查找指定服务的handle,如下代码:

struct svcinfo

上面就是service_manager.c中的检索服务代码,可以看出service_manager维护一张服务表svclist,可以根据服务名查找对应的结构体svcinfo,这个结构体里面就包含了需要的handle变量,handle值会被保存在BpBinder里面的mHandle变量里面。

2)binder_node是什么?下面是一段服务注册过程中的代码:

fp = (struct flat_binder_object *)(t->buffer->data + *offp);

来看一下bind_ref结构体:

struct binder_ref {

所以binder_node就是服务注册时传入的服务对象,其中第一个参数proc是代表Service Server的binder_proc,因为所有的服务实体都是注册到Service Server,而后面的binder_get_ref_for_node则是将该实体对应的引用注册到Context Manager,即Context Manager拥有所有服务实体对应的引用,Service Server拥有所有服务实体对象,下面是binder_node结构体:

struct binder_node {

其中proc是Service Server进程的binder proc地址,ptr是远程binder对象地址,即BpBinder,cookie是注册的本地服务的binder地址,每次Service Server接收到消息会先把cookie转换成对应的Service对象,然后根据传入的方法编号选择对应的方法执行生成结果数据,这样Service Server只要负责执行就行了,不用管服务对象的查找。

3)什么是binder_proc?首先看一下binder_open函数:

static int binder_open(struct inode *nodp, struct file *filp){

从上面函数可以看出每个进程调用binder_open都会生成自己的binder_proc,从binder_proc结构体可以看出进程间通信主要是靠每个进程在内核空间开辟的一块buffer,通信时一方会把自己的数据传到自己开辟的Buffer里面,然后binder driver负责将这些数据拷贝到目标进程的buffer里,然后唤醒目标进程处理数据就行了。

总结起来服务检索过程有如下几步:

  1. Context Manager(ServiceManager)进入待机状态,等待接收IPC数据。

  2. 调用服务的客户端生成并初始化binder_proc结构体,而后开辟一块buffer用于接收IPC应答数据

  3. 调用服务的客户端通过ioctl()调用binder driver的binder_ioctl()函数。与注册服务时一样,binder driver会查找Context Manager的binder_proc结构体。但与注册服务不同的是,它并不生成binder_node结构体,只是将IPC数据拷贝到Context Manager的接收buffer中。并且记下调用服务客户端的binder_proc结构体,以便查找IPC应答数据的接收端。

  4. Binder driver让调用服务的客户端处于待机状态,并唤醒处于待机状态的Context Manager,而后接收IPC数据。从待机状态苏醒的Context Manager在服务目录中查找请求的服务,把服务编号插入到IPC应答数据中,并把IPC应答数据传递给binder driver.

  5. Binder dirver将(4)中接收到服务编号去Context Manager中查找相应的binder_node结构体(先查找对应结构体的引用,引用里的一个属性就是binder_node),而后将查找到binder_node结构体注册到调用服务的客户端的binder_proc中。binder_node结构体用于在调用服务时查找Service Server的binder_proc结构体.

  6. Binder driver将(5)中注册的binder_node结构体的编号插入到IPC应答数据中,传递给客户端,然后唤醒客户端。在使用服务时,客户端将编号作为handle使用。

2、服务使用

经过服务检索,客户端获得了Service Server所拥有服务的binder_node,在生成IPC数据时,它就可以把要使用服务的binder节点编号设置到IPC数据的handle中,取代原来值为0的handle,服务使用有如下过程:

  • Service Server处于待机状态,等待接收IPC数据。

  • 客户端将从服务检索中获取的binder节点编号保存到IPC数据的handle(等于binder_ref中的desc)中,生成IPC数据后传递给binder driver,binder driver根据IPC数据中的handle查找相应的binder_ref结构体(ContextManager的binder proc结构体里面保存了所有的binder_ref对象,可以根据desc属性查找对应的binder_ref对象),然后获取binder_ref里面的binder_node对象,而binder_node结构体里面的proc属性就是注册该服务的Service Server的binder_proc地址。最后通过binder_proc结构体中binder_buffer结构体,将IPC数据拷贝到Service Server进程的buffer中。

  • Binder driver让客户端进入待机状态,唤醒处于待机状态的Service Server。Service Server从待机状态苏醒后接受IPC数据,并通过IPC数据中的RPC代码、RPC数据调用相应的服务函数。

  • 在服务函数执行完毕后,Service Server会生成IPC应答数据,并将其传递给binder driver,binder driver将IPC数据传递给客户端。至此,客户端调用服务的整个IPC过程就完成了。

总结

Android 提供的系统服务我们在开发过程中很多可以通过反射方式调用,不过系统也有提供接口给我们,比如context.getSystemService,不过getSystemService方法获取的是注册在SystemServiceRegistry里面的服务,里面的服务有的是来自系统服务;有的不是,比如Context.WINDOW_SERVICE就不是系统的,而是与当前进程绑定的 WindowManagerImpl(ctx);

Android Framework 入门学习相关推荐

  1. Android Framework入门介绍

    Android Framework入门介绍 https://blog.csdn.net/fu_kevin0606/article/details/79532710 framework概述 Androi ...

  2. Android安卓——入门学习

    在正式动手开发学习之前,首先了解一下安卓开发,让自己首先在主观印象中认识安卓的开发.所以本次学习主要是理论方面的知识,让大家对安卓有一个大概的了解. 本人在学习安卓时使用的是Android Studi ...

  3. Android.mk 入门学习

    我们还是采用RK3399的开发板来学习Android.mk NOTED: 在编译之前,我们需要source & lunch source build/envsetup.sh lunch rk3 ...

  4. Android 开发入门学习

    裴老师要我去看android里面的JAVA编程,LINUX内核.JAVA虚拟机等,要我下载个仿真器玩玩,搭个Eclipse环境写一下应用.这个任务已经很久了,但是我一直没有时间去做,那天导师来了,我什 ...

  5. Android测试入门学习

    一,Android测试新人练习--安装及文件传输 [课前准备] Android测试环境搭建 1.下载并安装JDK: http://www.oracle.com/technetwork/java/jav ...

  6. Android Studio入门学习(1)

    一.Android Studio下载安装 就不演示了 二.新建一个项目 在这里可以随便选择一个模板进行创建 给我的项目取一个名字,选择sdk版本,然后点击Finish,等待,这样一个项目就创建好了. ...

  7. 初学者必读Android开发入门之路

    初学者必读Android开发入门之路 [IT168评论]本人一直致力于嵌入式相关知识和技术在中国大陆地区的技术传播及嵌入式产品及移动设备的系统和应用程序开发,近两年主要专注于3G技术领域,重点是研究A ...

  8. Android开发入门一条龙

    Android开发入门学习,到上班到岗第一天安装软件,配置环境,一条龙服务.看这一篇就够了! 必看书籍 入门:<第一行代码-Android>下载地址 --零基础小白,无痛起步 入门:< ...

  9. Android FrameWork学习(二)Android系统源码调试

    点击打开链接 通过上一篇 Android FrameWork学习(一)Android 7.0系统源码下载\编译 我们了解了如何进行系统源码的下载和编译工作. 为了更进一步地学习跟研究 Android ...

最新文章

  1. 2022-2028年中国汽车修理行业市场前瞻与投资规划分析报告
  2. PTA基础编程题目集-7-4 BCD解密
  3. X431 元征诊断枪
  4. c#截取字符串后几位_基础库的字符串设计
  5. 延时加载refresh()方法
  6. 什么是Apache Spark?这篇文章带你从零基础学起
  7. 我的学习之路_第十四章_反射
  8. python面向过程实践汉诺塔_汉诺塔问题
  9. md5sum/opensll md5
  10. Python3.x+pycharm+Anaconda中缩小打包的.exe体积的方法
  11. 2021上半年软考数据库系统工程师真题完整版
  12. Win7系统用键盘替代鼠标的小技巧
  13. 爬虫练习-爬取起点中文网小说信息
  14. 计算机一级学科大学排名,大学计算机排名(一级学科)
  15. IDEA隐藏不想看见的文件
  16. 接口和抽象类练习:教练和运动员案例: (1)人员:乒乓球运动员和篮球运动员。乒乓球教练和篮球教练。 (2)为了出国交流,跟乒乓球相关的人员都需要学习英语。 请用所学知识分析,设计类和接口。
  17. 【思维导图】LAMPer技能树
  18. 操作系统-为什么进程之间的通信必须借助操作系统内核功能?
  19. lavarel5.2中多表联查 搜索后分页
  20. EasyUI API

热门文章

  1. php根据阅读记录推荐内容,php记录 - 作业部落 Cmd Markdown 编辑阅读器
  2. newcoder【链表分割】
  3. 浅谈 SurfaceView、TextureView、GLSurfaceView、SurfaceTexture
  4. android 辅助服务自动右滑,我的手机启用辅助功能后怎么滑动屏幕,是什么盲人的什么功能,怎么取消?...
  5. 门面模式:Facade(转自阿良.NET)
  6. 使用GitLab Pages托管静态网站
  7. ClickHouse 实现有序漏斗分析与数据可视化
  8. HTTP协议 - 初次见面 ,慢慢来(一)
  9. 计算机网络实验五——应用层和传输层协议分析
  10. 检查一片Flash好坏的流程