cwhbox / 技术 / 深入理解Android Sensor系统 (4.0)

0 0

   

深入理解Android Sensor系统 (4.0)

2012-08-15  cwhbox

曾几何时,本人写了一篇Android传感器初探"惊艳整个篮球场"...一转眼两年过去了,真是物逝人非,技术更新的快啊,如今都已经4.0巧克力冰激凌了...

0. 总论

本文希望分别从动态角度(应用程序进程)以及静态角度(框架体系架构)两方面来理解传感器系统。

1. 上层应用

从编写应用程序的角度来看,比较简单,大体分如下4步,便可得到一个传感器实时上报的数值并作处理,

1) 得到传感器服务  getSystemService(SENSOR_SERVICE);

得到一个SensorManager,用来管理分配调度处理Sensor的工作,注意它并不服务运行于后台,真正属于Sensor的系统服务是SensorService,终端下#service list可以看到sensorservice: [android.gui.SensorServer]。

2) 得到传感器类型 getDefaultSensor(Sensor.TYPE_GRAVITY);

 当然还有各种千奇百怪的传感器,可以查阅Android官网API或者源码Sensor.java。

3) 注册监听器 SensorEventListener

应用程序打开一个监听接口,专门处理传感器的数据,这个监听机制比较重要,被系统广泛使用。

4) 实现监听器的回调函数 onSensorChanged, onAccuracyChanged 

例如对重力感应器的xyz值经算法变换得到左右上下前后方向等,就由这个回调函数实现。


1.1 进程空间

一个应用程序对应一个虚拟机实例,一个进程和一个主线程,通过主线程控制四大组件。

要想得到传感器数据,须要开一个子线程,通过pol轮训的方式监听底层上报的数据,再由消息机制把数据发送给主线程处理。

换句话说,应用程序有两个任务:

1)准备一个监听接口供主线程接受数据

2)开启一个子线程接受底层数据并发送到主线程,

而这些有关Sensor的具体任务,全部交给SensorManager统一管理。

1.2 Android SDK API

上层通过SDK API得到Java框架,这里,应用程序通过AIDL接口远程调用(RPC)得到SensorManager.

可查阅官网SDK API android.hardware.SensorManager类提供的方法。


简单粗暴概括地讲,上层要拿底层数据,无外乎两部分,

1)设备的类型 (控制流)

getSensorList()得到传感器类型,取得sensorList列表的过程由上至下,java框架->JNI->本地框架 ->标准抽象层->设备驱动

2) 设备的数据 (数据流)

registerListener()注册监听器的时候会开启一个线程,其中sensor_data_poll同样由上至下最后拿到底层数据。

写到这里,摘抄别人的一段话...

我们在学习新系统时,首先映入眼帘的就是新概念。新名词,就如现在我们面临的Android大量的新名词,在程序员的世界都是从代码实践开始的,是从写应用开始去涉及。SDK给了我们一个概念,我们就在这个概念框架下,使用SDK给我提供的函数接口,数据结构,初始化过程等,我们最初的接触到原型就是“HelloWorld”之类的DEMO程序,我们在Hello world上去使用各种不同的接口函数,对于应用程序员来讲,他说看到的系统就是系统调用接口,及其编程开发流程。实际上只要一使用这些接口,就不得不接受一系列的概念,只有在这种概念系统下,我们才能工作。但是,实际上我们却忽略了这样的概念系统的理解,只是在编程接口的这个狭窄的空间去理解系统.我们理解系统在形成理解概念的空间只是微小的一角,很少有资料来介绍这种概念系统的形成和理解,编程接口只是这个概念空间一个,对外部的一个表征。我们可以抽象起来,以接口,协议和行为,来描述系统的情况。SDK API的实质向上层提供了一个语义接口,从而在层间实现了一个转义过程,同时又成为一个功能的集合体。但是我们很少这样跳出来看,我们到底是处于一种什么样的概念空间,SDK除了调用接口外,还给了我们怎样一种整体概念?目标系统的基本构架在本质上的东西就是一个概念系统到另一个概念系统的映射。让我们大脑理解的概念系统映射到计算机能实现的概念域的一个映射。我们假定这个概念域E,机器能够理解的概念域为M,我们的软件工程要做的事情实质就是:EàM领域的一个映射过程。


2 Java框架

上层由getSystemService(SENSOR_SERVICE);得到一个SensorManager实例,为上层提供方法。

除了上文的两个method,SensorManager本身的构造函数很有必要看下,


nativeClassInit(); 在JNI层得到android.hardware.Sensor的JNI环境指针env.

sensors_module_init(); 通过JNI调用本地框架,得到SensorService,SensorService初始化控制流各功能。

new Sensor(); 建立一个Sensor对象,可查阅官网API android.hardware.Sensor

sensors_module_get_next_sensor(); 上层得到设备支持的所有Sensor,并放入SensorList链表。

new SensorThread(); 创建Sensor线程,当应用程序registerListener()注册监听器的时候开启线程run(),注意当没有数据变化时,线程会阻塞。

站在上层的角度,我们看不到SensorManager做了两件重要的工作,即

1) 得到本地框架SensorManager.cpp,获得Sensor真正的后台服务SensorService

2) 创建EventQueue用来管理数据,这个是4.0新版本的一大变化,这个变化,导致抽象层有关数据流的内容全部重写...


3 本地框架

为了不陷入茫茫的代码海洋,这里简单的做个总结,

SensorManager负责控制流,通过C/S binder机制与SensorService通信。

SensorEventQueue负责数据流,通过管道机制读写底层数据。


SensorSevice把任务交给SensorDevice,SensorDevice调用标准的抽象层接口。

Sensor架构的抽象层接口是最标准的一种,它很好的实现了抽象层与本地框架的分离。

当然还有其它类型的抽象层接口,这里不作讨论。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。如发现有害或侵权内容,请点击这里 或 拨打24小时举报电话:4000070609 与我们联系。

    来自: cwhbox > 《技术》

    猜你喜欢

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多