Android硬件访问服务框架思想初识

 Android的硬件访问服务提供了一个APP调用硬件实现的方法模型。我们从上往下来看。应用层面对的都是一个个的服务叫service.比如电源管理服务,震动服务等等。应用层代码首先就需要去查询系统是否存在这么一个服务,或者目前是不是可以被获取的。从这个角度,我们就牵扯出来两个问题。a:既然去系统里面查找这么个服务,那么首先应该又什么地方注册加入系统的。b:有了这么个服务,我也得创建一个接口函数来链接APP跟这个服务函数的桥梁。我们的应用APP通过这么一个桥梁来去访问这个服务。
我们需要怼的就是这么个服务是怎么添加到系统的,以及他的前世今生。这个工作是由systemserver.java文件来做的。在 startotherservices函数中我们先去new 一个服务实例对象,然后再去addservice 将这个方法注册到系统的service_manager.c这就是前面我说的系统。那么这个服务的方法是根据谁来实例化的呢?那么肯定会有一个class类来做,也就是说我们需要创建这么一个类。
APP操作的根源还是在底层,现在我们讲好了service,那么我们还需要一个地方去注册管理底层的方法。这个仍旧是在SystemServer.java里面集中管理。这个是通过Loadlibrary函数调用JNIonload。cpp这里面并没有直接做JNI的处理,因为安卓各个方法如果都写在这么一个文件里面就会显得特别乱。我们继续通过调用下一层的JNI文件来处理。这个JNI文件是需要随着系统一起编译的。后期我们没改一次JNI就去编译一次Anroid系统,太费劲了。我们就引入了Hal文件。我们的jni只需要提供标准的接口。hal文件去实现这些jni。而且这些hal文件不需要跟着系统一起编译,我们还可以把他做成.so文件,加载到库里。这样同时还解决了保密问题。对吧。
说的还是挺绕的。简而言之。我们把底层各种封装处理,然后提供处理啊那么一个插头(我们的service实例化后的方法就是一个插头,里面包含了各种处理)。我们的应用层也使用一个插头,当这俩插头接到了一起,就实现了我们的安卓硬件访问服务。

如果某个硬件资源只能被某一个应用使用,可以使用下面的方法访问硬件:

JAVA APP--->JNI_OnLoad()加载C库---->将JAVA三个地方法与C库函数进行关联并注册---->调用JAVA本地Native方法就可以访问C库的C接口------>进而访问硬件驱动中的open, read, write,从进访问硬件。

但是,以上场景仅限于只有一个APP使用这个硬件资源,如果有多个应用想要使用某个硬件时,如果还按上面方法,必须会造成硬件资源的冲突,所以此时需要有一种框架来解决这个问题。解决方案就是访问硬件资源的程序只能并且只有一个,我们称之为System Server, 其它要访问这个硬件资源的APP必须要给Server发请求,由Server间接的操作硬件,从而实现资源的访问。这个就称之为硬件访问服务。

关于硬件访问服务需要注意以下几点:
1 System Server是由JAVA编写的,所以它要想访问硬件,必须要加载JNI的C库(Loadlibrary).
2 C库的JNI_Onload函数里要注册本地方法,分别调用各个硬件的函数来注册本地方法。比如LED,振动器,有串口。。。等等。。
3 System Server:
(1)对每个硬件都要添加服务,add service
前提需要实现的是:对每个硬件构造service,使用本地Native方法
(2)对于(1)添加的服务就是向service_manager.c注册,比如serialservice, vibratorservice, ledservice等。如果JAVA应用程序需要使用某些Service的时候,就需要通过这个Service_manager查询及获取相应的Service。

4 最终APP怎么使用?
(1)APP使用之前需要获得这个服务getService
(2)最后就是使用这个服务了。执行Service的方法

以后修改硬件驱动的时候,把驱动文件放在hal里面,如hal_led.c,有几个好处:
(1)容易修改
(2)很多公司不愿意开放其硬件操作,他们只提供so文件,出于保密的目的。
试想一下,如果把硬件操作源代码放到JNI文件里,如果要修改,需要编译整个工程,此外,硬件源代码暴露出来了,保密性不好。


分析一下:
以上操作涉及到三个进程, 
1 SystemServer进程:它提供的功能如下:
---a: 它向service_manager.c注册服务
---b: 加载硬件Service JNI 的C库
---C: 接收其它app的硬件操作请求,访问硬件资源

2 Service_Manager进程:负责硬件资源各种Service的注册添加,以及接怍JAVA应用app的各种service查询请求及资源的获取。

3 JAVA应用APP进程,它其实是一个客户端,它首先向Service_Manager查询获得某一个Service, 最后,把这个Service发送给SystemServer进程以请求相应的服务,

而以上三个进程之间的内部通信,主要依靠Android内核的Binder Driver系统进行内部进程间通信。这个Binder并不是linux内核自带的,是google公司对linux内核进行修改添加的一个驱动程序,可实现更加高效的进程间通信。

ps:注册Server与Service的区别,可以这么理解,Server服务器提供各种服务Services.




思考:如何实现一个硬件访问服务。
1 编写JNI和HAL,以led为例,先编写com_android_server_ledservice.cpp,用于注册JNI本地方法。再编写hal_led.c,里面就是实现open,read,write等硬件访问接口。
2 修改onload.cpp,调它调用com_android_server_ledservice.cpp内实现的函数,
3 修改system server.java, 
new ledservice()
add ledservice()
4编写LEDService.java提供一个类,做接口用的,他自己是不能调用本地方法的。他是通过在systemserver.java中实例化对象提供接口来实现功能的!!这个地方要谨记,很容易让人混沌不清。
5 编写ILEDService.java接口给app使用。


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/403976.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu更新过程被中断后的问题

From: http://defe.me/os/368.html Ubuntu的更新过程是先下载完源里的文件就开始执行升级,如果涉及到一些因为版权或是其他问题没加入源的文件,在升级安装的中途再从第三方服务器上下载。有时需要下载的文件比较大,而网速又不给力&#xff0c…

机器码和字节码

什么是机器码 机器码 机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。 通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速…

shell脚本常用语句用法笔记

脚本基本语句用法笔记 grep -i 查询时不区分大小写 -n打印匹配的行号 -v 打印不匹配的行 -AX包括每次匹配之后X行 -BX包括每次匹配之后X行 cat /etc/passwd |grep student (-i 表示不关心大小写) 正则表达式中 ^代表开始 $代表结束 cat /etc/passwd|grep ^# -v (…

CI框架分页类

分页类1.分页类参数说明 base_url > 指向你的分页所在的控制器类/方法的完整的 URL, total_rows > 数据的总行数, per_page > 每页显示的项目, uri_segment > 自动检测哪一段包含页数, num_links > 放在当前页前后显示的链接数, 2.分页类使用 $this->load-&g…

对象运算符.和[]的用法

相同点:它们的第一个运算数都是对象或者数组。 区别:"."将第二个运算数作为对象的属性读写。第二个运算数只能是合法的标识符 "[]"将第二个运算数作为数组的下标来读写。第二个运算数可以是任何类型的值甚至是undefined,…

Linux中对文件描述符的操作(FD_ZERO、FD_SET、FD_CLR、FD_ISSET

在Linux中,内核利用文件描述符(File Descriptor)即文件句柄,来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。宏FD_ZERO、F…

Host SMBus controller not enabled的解决方法

From: http://blog.csdn.net/starmlk/article/details/7982077 SMBus 目录 SMBus与I2C的差别SMBus 是 System Management Bus 的缩写,是1995年由Intel提出的,应用于移动PC和桌面PC系统中的低速率通讯。它主要是希望通过一条廉价并且功能强大的总线&…

gitlab服务器搭建

搭建教程:http://blog.csdn.net/discoverer100/article/details/51814171#reply

【Bugly干货分享】微信文件微起底Ⅰ

Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处 微信大家都在用,但微信的本地文件到底隐藏着什么样的信息呢…

如何使antd中table表格不换行

.ant-table-thead > tr > th{ white-space:nowrap; } .ant-table-row td{ white-space:nowrap; } 在对用的组件style加上上面代码

由旋转矩阵求旋转中心

在图像的复合变化过程中,通常会用到Matrix矩阵,一般的过程是先构造仿射变换矩阵,然后对图像进行仿射变换,如:围绕点(100,100)旋转30度(sin 30 0.5 ,cos 30 0.866)&…

git服务器搭建

本文主要记录在Ubuntu 16.04操作系统中搭建GitLab服务器的操作记录,以下是操作步骤(主要参考资料:https://about.gitlab.com/downloads/#ubuntu1604)。1.安装依赖包,运行命令sudo apt-get install curl openssh-server…

Ubuntu桌面版网络设置

先来说下我的经验吧,我觉得Ubuntu桌面版中网络配置最好的方法是用Network-Manager这个带界面的软件,因为桌面版中这个软件是自动启动的。理由如下: 1. 如果要把这个软件设置为开机时不启动,得执行:chkconfig network-…

ant-design之form-重置表单多个值

重置form表单中的某一个值或者一次重置多个值 watch: {databaseType: function(curr, old) {this.getMyTableData [];this.form.resetFields([databaseSource,"databaseName","tableName",""]);},},

2016matlab安装

百度云的下载链接(永久有效)链接:https://pan.baidu.com/s/1dGZB4q9 密码:pfl3Matlab用途:点击打开链接与网盘资源相对应的安装教程1.将网盘中的3个文件下载下来后,解压(在当前路径下&#xff0…

C#类、接口、虚方法和抽象方法-抽象类与接口的区别与联系

C#抽象类和接口之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于抽象类和接口的选择显得比较随意。其实,两者之间还是有很大的区别的。首先,以抽象类的方式定义一个公共的…

Nginx_查看并发连接数

通过查看Nginx的并发连接,我们可以更清除的知道网站的负载情况。Nginx并发查看有两种方法(之所以这么说,是因为笔者只知道两种),一种是通过 web界面,一种是通过命令,web查看要比命令查看显示的结…

struct作为map的key时,需要重载该结构体

当结构体作为map中的key时&#xff0c;这个结构体必须重载"<"运算符, 否则将出错&#xff0c;看我完整代码&#xff1a; #ifndef WIN32#include <string.h>#else#include <string>#endif#include <iostream>#include <map>using namespa…

解决vuex中store保存数据,刷新页面会清空得问题

1.在App.vue下加入 mounted() {window.addEventListener("unload", this.saveState);},methods: {saveState() {sessionStorage.setItem("state", JSON.stringify(this.$store.state));}}2.在store下的index.js文件下修改 state:sessionStorage.getItem(…

arm MMU详解

一、MMU的产生许多年以前&#xff0c;当人们还在使用DOS或是更古老的操作系统的时候&#xff0c;计算机的内存还非常小&#xff0c;一般都是以K为单位进行计算&#xff0c;相应的&#xff0c;当时的程序规模也不大&#xff0c;所以内存容量虽然小&#xff0c;但还是可以容纳当时…