这里再来看一下SensorThread线程是怎么监听数据的
首先看一下流程图
我们来看一下SensorThreadRunnable的run方法
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()) {//创建一个到service的连接queue
return;
}
synchronized (this) {
// we've open the driver, we're ready to open the sensors
mSensorsReady = true;
this.notify();
}
while (true) {
// wait for an event
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)) {//把数据发送到所有的监听了这个sensor的listener
// this is asynchronous (okay to call
// with sListeners lock held).
listener.onSensorChangedLocked(sensorObject,
values, timestamp, accuracy);
}
}
}
}
}
//Log.d(TAG, "exiting main sensor thread");
}
这里open创建一个queue
private boolean open() {
// NOTE: this cannot synchronize on sListeners, since
// it's held in the main thread at least until we
// return from here.
sQueue = sensors_create_queue();
return true;
}
sensors_create_queue是一个jni的接口
static jint
sensors_create_queue(JNIEnv *env, jclass clazz)
{
SensorManager& mgr(SensorManager::getInstance());
sp<SensorEventQueue> queue(mgr.createEventQueue());
queue->incStrong(clazz);
return reinterpret_cast<int>(queue.get());
}
调用SensorManager的createEventQueue
sp<SensorEventQueue> SensorManager::createEventQueue()
{
sp<SensorEventQueue> queue;
Mutex::Autolock _l(mLock);
while (assertStateLocked() == NO_ERROR) {
sp<ISensorEventConnection> connection =
mSensorServer->createSensorEventConnection();//创建一个连接
if (connection == NULL) {
// SensorService just died.
ALOGE("createEventQueue: connection is NULL. SensorService died.");
continue;
}
queue = new SensorEventQueue(connection);?/以connection为参数创建一个SensorEventQueue
break;
}
首先调用createSensorEventConnection,对应到SensorService里面
sp<ISensorEventConnection> SensorService::createSensorEventConnection()
{
sp<SensorEventConnection> result(new SensorEventConnection(this));
return result;
}
这里newSensorEventConnection
SensorService::SensorEventConnection::SensorEventConnection(
const sp<SensorService>& service)
: mService(service), mChannel(new BitTube())
{
}
这里new在service端new 了一个BitTube
回到SensorManager::createEventQueue,接下来queue =new SensorEventQueue(connection)新建了一个queue
我们看到在SensorEventQueue里有一个
void SensorEventQueue::onFirstRef()
{
mSensorChannel = mSensorEventConnection->getSensorChannel();
}
这样在第一次使用智能指针引用SensorEventQueue时就会调用onFirstRef获得一个和service通信的BitTube
到这里sensors_create_queue就成功创建了一个和service通信的queue
回到SystemSensorManager的run函数
接下来调用sensors_data_poll检测是否有数据到来
sensors_data_poll也是一个jni的函数
static jint
sensors_data_poll(JNIEnv *env, jclass clazz, jint nativeQueue,
jfloatArray values, jintArray status, jlongArray timestamp)
{
sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
if (queue == 0) return -1;
status_t res;
ASensorEvent event;
res = queue->read(&event, 1);//从queue中读数据
if (res == 0) {
res = queue->waitForEvent();
if (res != NO_ERROR)
return -1;
// here we're guaranteed to have an event
res = queue->read(&event, 1);
ALOGE_IF(res==0, "sensors_data_poll: nothing to read after waitForEvent()");
}
if (res <= 0) {
return -1;
}
jint accuracy = event.vector.status;
env->SetFloatArrayRegion(values, 0, 3, event.vector.v);
env->SetIntArrayRegion(status, 0, 1, &accuracy);
env->SetLongArrayRegion(timestamp, 0, 1, &event.timestamp);
return event.sensor;
}
这里read
ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents)
{
return BitTube::recvObjects(mSensorChannel, events, numEvents);
}
就从前面创建的和service 的通道中读数据
这样,从sensor传感器来的数据就能传到应用 了。