相关文件目录:/frameworks/base/core/java/android/hardware/SensorManager.java
这个SensorManager主要负责返回传感器类型,从底层获得数据。getSystemService(Stringname)是根据名字返回相应的Manager,这个机制也比较重要,网上有相关资料,在此不展开讨论了;mSensorManager.getDefaultSensor(type)就是获取指定类型的传感器。这些类型在API手册中都能查到,包括温度传感器,重力感应器等。registerListener注册监听器,这是为了能让ManagerSensor回调正确的接口函数,注册的时候我们可以指定sensor的灵敏度,分四个等级,API手册中有相应介绍。
我们来看一下SensorManager的构造函数,它总共干了3件事。
1.获取windowManager实例,监控屏幕旋转状态;
2.调用sensors_module_init()和sensors_module_get_next_sensor()两个JNI方法,初始化sensorList传感器列表;
3.构造SensorThread线程但却没有开启线程,开启是在registerListener里面。
public SensorManager(Looper mainLooper) {
mMainLooper = mainLooper;
synchronized(sListeners) {
if (!sSensorModuleInitialized) {
sSensorModuleInitialized = true;
nativeClassInit();
//1.获取windowManager实例,并监控屏幕旋转状态
//获取windowManager实例
sWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
//监控屏幕旋转状态
if (sWindowManager != null) {
// if it's null we're running in the system process
// which won't get the rotated values
try {
sRotation = sWindowManager.watchRotation(
new IRotationWatcher.Stub() {
public void onRotationChanged(int rotation) {
SensorManager.this.onRotationChanged(rotation);
}
}
);
} catch (RemoteException e) {
}
}
//2.初始化sensorList传感器列表
//调用了sensors_module_init()JNI方法
sensors_module_init();
final ArrayList<Sensor> fullList = sFullSensorsList;
int i = 0;
do {
Sensor sensor = new Sensor();
//调用了sensors_module_get_next_sensor()JNI方法
i = sensors_module_get_next_sensor(sensor, i);
if (i>=0) {
//Log.d(TAG, "found sensor: " + sensor.getName() +
// ", handle=" + sensor.getHandle());
sensor.setLegacyType(getLegacySensorType(sensor.getType()));
fullList.add(sensor);
sHandleToSensor.append(sensor.getHandle(), sensor);
}
} while (i>0);
//3.构造SensorThread线程,但是这里并没有开启线程
sSensorThread = new SensorThread();
}
}
}
registerListener
registerListener里面开启了SensorThread线程,SensorThread是一个死循环,他通过调用native方法sensors_data_poll来轮询下层发来的传感器数据。每次接受到一个数据就会调用代理listener中的onSensorChangedLocked方法,把它封装成一个消息发给自己的messagerHandler,在这里面最终调用注册的onSensorChanged方法,也就是我们上面应用程序接口的中方法。
public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) {
return registerListener(listener, sensor, rate, null);
}
public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate,
Handler handler){
if (listener == null || sensor == null) {
return false;
}
boolean result = true;
int delay = -1;
switch (rate) {
case SENSOR_DELAY_FASTEST:
delay = 0;
break;
case SENSOR_DELAY_GAME:
delay = 20000;
break;
case SENSOR_DELAY_UI:
delay = 60000;
break;
case SENSOR_DELAY_NORMAL:
delay = 200000;
break;
default:
delay = rate;
break;
}
synchronized (sListeners) {
// look for this listener in our list
ListenerDelegate l = null;
for (ListenerDelegate i : sListeners) {
if (i.getListener() == listener) {
l = i;
break;
}
}
// if we don't find it, add it to the list
if (l == null) {
l = new ListenerDelegate(listener, sensor, handler);
sListeners.add(l);
// if the list is not empty, start our main thread
if (!sListeners.isEmpty()) {//如果list不为空,调用sSensorThread.startLocked()开启线程
if (sSensorThread.startLocked()) {
if (!enableSensorLocked(sensor, delay)) {
// oops. there was an error
sListeners.remove(l);
result = false;
}
} else {
// there was an error, remove the listener
sListeners.remove(l);
result = false;
}
} else {
// weird, we couldn't add the listener
result = false;
}
} else {
l.addSensor(sensor);
if (!enableSensorLocked(sensor, delay)) {
// oops. there was an error
l.removeSensor(sensor);
result = false;
}
}
}
return result;
}
在startLocked中使用start()方法启动一个线程后,系统为该线程分配了除CPU外的所需资源,使该线程处于//可运行状态(Runnable),系统通过调度选中一个Runnable的线程,使其占有CPU并转为运行//中状态(Running).此时,系统真正执行线程的run()方法.
boolean startLocked(){
try {
if (mThread == null) {
mSensorsReady = false;
SensorThreadRunnable runnable = new SensorThreadRunnable();
Thread thread = new Thread(runnable, SensorThread.class.getName());
thread.start();
synchronized (runnable) {
while (mSensorsReady == false) {
runnable.wait();
}
}
mThread = thread;
}
} catch (InterruptedException e) {
}
return mThread == null ? false : true;
}
线程的run函数用反复调用sensors_data_poll反复调用轮询下层发来的传感器数据,每次接受到一个数据就会调用代理listener中的onSensorChangedLocked方法,把它封装成一个消息发给自己的messagerHandler,在这里面最终调用注册的onSensorChanged方法,也就是我们上面应用程序接口的中方法
public void run() {
//Log.d(TAG, "entering main sensor thread");
final float[] values = new float[3];
final int[] status = new int[1];
final long timestamp[] = new long[1];
Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
if (!open()) {
return;
}
synchronized (this) {
// we've open the driver, we're ready to open the sensors
mSensorsReady = true;
this.notify();
}
while (true) {
// 等待下层发来的传感器数据
final int sensor = sensors_data_poll(sQueue, values, status, timestamp);
int accuracy = status[0];
synchronized (sListeners) {
if (sensor == -1 || sListeners.isEmpty()) {
// we lost the connection to the event stream. this happens
// when the last listener is removed or if there is an error
if (sensor == -1 && !sListeners.isEmpty()) {
// log a warning in case of abnormal termination
Log.e(TAG, "_sensors_data_poll() failed, we bail out: sensors=" + sensor);
}
// we have no more listeners or polling failed, terminate the thread
sensors_destroy_queue(sQueue);
sQueue = 0;
mThread = null;
break;
}
final Sensor sensorObject = sHandleToSensor.get(sensor);
if (sensorObject != null) {
// report the sensor event to all listeners that
// care about it.
final int size = sListeners.size();
for (int i=0 ; i<size ; i++) {
ListenerDelegate listener = sListeners.get(i);
if (listener.hasSensor(sensorObject)) {
// this is asynchronous (okay to call
// with sListeners lock held).
//接收到一个数据就会调用onSensorChangedLocked方法
listener.onSensorChangedLocked(sensorObject,
values, timestamp, accuracy);
}
}
}
}
}
//Log.d(TAG, "exiting main sensor thread");
}
onSensorChangedLocked方法,把接收到的数据封装成一个消息发给自己的messagerHandler。
SensorEvent t = getFromPool();
final float[] v = t.values;
v[0] = values[0];
v[1] = values[1];
v[2] = values[2];
t.timestamp = timestamp[0];
t.accuracy = accuracy;
t.sensor = sensor;
Message msg = Message.obtain();
msg.what = 0;
msg.obj = t;
mHandler.sendMessage(msg);
}
}
在Application Framework层中我们需要Libraries层中JNI的支持
我们需要以下几个JNI方法
ensors_module_init
sensors_module_get_next_sensor
sensors_data_poll