四、Android硬件访问服务框架

Android硬件访问服务框架

一 概括

前边内容做了,安卓应用程序通过加载C库,访问硬件驱动程序最终点亮或熄灭LED,我们称为,通过JNI接口直接访问
在这里插入图片描述

实际上,安卓系统有可能几个应用程序同时访问一个硬件,可能就会出现问题,怎么办呢,我们一个应用程序访问硬件,这个应用程序就是SystemServer,由它来访问硬件,其他的应用程序APP将访问硬件的请求发给systemserver,由它统一管理,这就是硬件访问服务。
在这里插入图片描述

  1. SystemServer通过loadlibrary 加载C库。
    硬件底层都是用C写的,systemserver用java写的,中间肯定要通过JNI接口,所以加载C库

  2. 在C库的JNI_Onload 函数中注册本地方法。
    系统中有许多硬件,LED,LCD声卡等,每个硬件的本地操作函数都不一样,在这个函数中,分别调用各个硬件的函数来注册本地方法

  3. SystemServer,对每个硬件使用本地方法来构造Service,添加服务addService到系统当中

  4. 最终 APP怎么使用,首先获得服务getService,然后使用服务即执行Service方法,这样应用程序获得Service之后就可以通过本地方法来操作硬件了

二 结合安卓源代码分析

  • 过程框图
    在这里插入图片描述
    在这里插入图片描述
  • 从Android源代码中提取其中文件夹,建立sourceinsight工程
    在这里插入图片描述
第一步
  • 在SystemServer.java文件中main 调用了SystemServer的run方法,在run中可以找
    System.loadLibrary("android servers") 用于加载C库,对应的C库文件是onload.cpp
    在这里插入图片描述
    在这里插入图片描述
第二🙅步
  • 我们知道只要一加载c库,就会调用JNI_Onload, 在onload.cpp中肯定有一个 JNI_Onload()函数,分别调用各个硬件有关的函数来注册本地方法,如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sIPDHR7j-1581150024156)(C:\Users\14629\AppData\Roaming\Typora\typora-user-images\image-20200208104524030.png)]
    这些函数是分别在某个文件中定义的,有个共同的特点,函数名加上com前缀就是对应的C文件,比如VibratorService 对应的C文件就是 com_android_server_VibratorService.cpp,
第三步
  • 在这个文件中可以看到com_android_server_VibratorService.cpp 中调用了 jniRegisterNativeMethods() 方法,注册本地方法,每个硬件函数的本地方法都不一样,每个硬件对应的这个.cpp文件称之为JNI文件
    在这里插入图片描述
第四步

操作比较简单的可以直接在.cpp的JNI文件中直接调用操作硬件的函数比如open write等函数来访问驱动程序,但是如果硬件操作比较复杂,可以单独把对硬件的操作写在hal文件中,比如 hal_led.c led_driver,Hal是表示硬件抽象层

  1. 容易修改。这样以后如果修改了硬件操作只需要修改Hal文件就可以了,将对应的so文件放到系统中去就可以了,但是如果在JNI文件中修改硬件的话,一旦需要修改就要编译整个系统。
  2. 保密。很多公司并不愿意开发硬件操作,只提供so库,让jni直接加载so文件就可以用了
第五步
  • 对每个硬件都构造一个Service,然后addService,这个Service肯定会用到上步注册的本地方法
    在SystemServer.java中 加载完c库后有调用 startOtherServices() 在这个方法中定义了各种Service
    在这里插入图片描述
    在这里插入图片描述
    例如:振动器的服务 VibratorService 查找 vibrator
    在这里插入图片描述
    首先是实例化了一个振动器的服务对象,这就是构造Service,会调用到本地方法,然后通过addService() 将这个服务告诉系统,这个系统就是service_manager.c 管理了系统中的所有服务,要想硬件的Service被系统应用使用,必须注册进service_manager
    怎么实例化Service服务,里边肯定会调用到本地方法,是个java文件 VibratorService.java
    在这里插入图片描述
    搜索native方法,肯定被用到了,这就是服务还是调用的native方法
第六步
  • 应用程序就可以通过向service_manager 查询获得某个Service,获取的是ILedService这样的接口,从框图可以看出来,addService的时候是LedService.java,而应用程序getService的时候操作的是ILedService.java,所以应用程序获得的是接口,I表示接口。
第七步
  • 应用程序通过ILedService这样的接口把对硬件的操作请求发送给LedService这样的的服务,由这个服务实现对硬件的操作。
整个操作过程涉及到三个进程
  1. 第一个进程是SystemServer向service_manger注册添加各种Service服务,对应第五步
  2. 然后应用程序实际上就是客户端,向server_manger查询获得某一个服务的接口,对应第六步
  3. 应用程序将对硬件操作的服务请求发送给SystemServer,对应第七步
  • 这些进程间的通信时通过linux内核的Binder driver实现的,以上几步都涉及到Binder driver,这个驱动程序并不是内核自带的,而是谷歌公司对linux内核做了修改添加了,添加了一个驱动程序,它可以更高效的实现进程间通信

总结:怎么实现硬件访问服务

1. JNI 和HAL
  • 写出 com_android_server_LedService.cpp
  • 在其中添加jniRegisterNativeMethods() 实现注册JNI本地方法。
  • hal_led.c 中可以调用硬件访问函数,open write等
  • 在JNI文件中加载hal
2. 修改onload.cpp
  • 调用JNI文件实现的函数
3. 修改SystemServer.java
  • 构造硬件服务 new LedService
  • 添加服务到系统 addService

4. LedService.java

  • 调用本地方法实现硬件操作
5. ILedService.java
  • 应用程序要获得服务接口,给APP使用
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AIOT技术栈

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值