您的位置:首页 > 移动开发 > Android开发

Android 2.3.5 sensors 个人梳理总结

2013-11-11 13:45 597 查看
一、sensors种类
方向传感器
publicstatic final int SENSOR_ORIENTATION = 1 << 0;
加速度感应器
publicstatic final int SENSOR_ACCELEROMETER = 1 << 1;
温度感应器
publicstatic final int SENSOR_TEMPERATURE = 1 << 2;
地磁感应器
publicstatic final int SENSOR_MAGNETIC_FIELD = 1 << 3;
亮度感应器
publicstatic final int SENSOR_LIGHT = 1 << 4;
距离感应器
publicstatic final int SENSOR_PROXIMITY = 1 << 5;
三度仪感应器
publicstatic final int SENSOR_TRICORDER = 1 << 6;
方向感应器
publicstatic final int SENSOR_ORIENTATION_RAW = 1 << 7;
publicstatic final int SENSOR_ALL = 0x7F;

二、相关的文件
frameworks/base/core/java/android/hardware/目录下:
SensorEvent.java SensorEventListener.java Sensor.java
SensorListener.java SensorManager.java
frameworks/base/core/jni/android_hardware_SensorManager.cpp
frameworks/base/include/gui/目录下:
ISensorEventConnection.h ISensorServer.h SensorChannel.h SensorEventQueue.h Sensor.h SensorManager.h
frameworks/base/libs/gui/目录下:
ISensorEventConnection.cpp ISensorServer.cpp SensorChannel.cpp Sensor.cpp SensorEventQueue.cpp SensorManager.cpp
frameworks/base/services/sensorservice/目录下:
GravitySensor.cpp GravitySensor.h LinearAccelerationSensor.cpp LinearAccelerationSensor.h RotationVectorSensor.cpp RotationVectorSensor.h SecondOrderLowPassFilter.cpp SecondOrderLowPassFilter.h SensorDevice.cpp
SensorDevice.h SensorInterface.cpp SensorInterface.h SensorService.cpp SensorService.h
hardware/libhardware/include/hardware/sensors.h





三、SensorServer的启动过程。
1、frameworks/base/services/java/com/android/server/SystemServer.java中调用init1().



2、frameworks/base/services/jni/com_android_server_SystemServer.cpp调用android_server_SystemServer_init1().



3、frameworks/base/cmds/system_server/library/system_init.cpp调用system_init(),在其中执行了SensorService::instantiate();



4、在frameworks/base/services/sensorservice/SensorService.cpp中是没有instantiate()这个方法的,所以我们需要看它的父类。在frameworks/base/services/sensorservice/SensorService.h中我们发现classSensorService
:public BinderService<SensorService>,publicBnSensorServer,
。是有2个父类的。
其中BnSensorServer是binder通信的本地实现。而BinderService是一个模板类。其中的静态函数instantiate()是调用了自身的静态函数publish(),在这个函数中会newSensorService(),并且把它add到servicemanager中去。





5、SensorService::SensorService()先看下SensorService的构造函数,发现只是初始化了几个变量。



6、SensorService::onFirstRef().首先这个函数是在第一次新增引用计数时,会调用此函数。在这里当SensorService对象创建好了,并且添加到servicemanager中,会增加一次对SensorService对象的引用。所以这个方法一定会被调用。
(关于onFirstRef()的实现可以去了解下:AndroidC++层的内存收回主要是通过三个类来实现,分别是RefBase,sp,wp;)



7、在SensorService::onFirstRef()中,首先定义了一个SensorDevice的变量(SensorDevice&dev(SensorDevice::getInstance());),然后再initCheck(),如果没有错误,就会调用getSensorList()获取到所有的sensors,并且保存在sensor_tconst*list;中。并且每个sensor都会通过调用函数registerSensor注册到SensorService中去,其实也就是添加到变量mSensorList、mSensorMap、mLastEventSeen中去。
最后执行run("SensorService",PRIORITY_URGENT_DISPLAY);就会执行到SensorService::threadLoop()中去。
其中SENSOR_TYPE_GRAVITY,
SENSOR_TYPE_LINEAR_ACCELERATION,
SENSOR_TYPE_ROTATION_VECTOR
如果没有找到的话,就会注册一个虚拟的Sensor,也就是说一个空实现的sensor。
8、在SensorService::threadLoop()中。首先就是申请一些空间变量,然后就进入一个循环,在这个循环中,我们通过device.poll()读取事件,如果读取不到就会一直阻塞在这里。当读取成功了就会首先把这次事件通过recordLastValue()函数保存为上次的事件,然后把事件发送给所有建立连接的SensorEventConnection的客户端。(其中SensorEventConnection的建立,我们可以通过另一个途径来分析)





外传、SensorDevice::getInstance()这个函数的实现。首先我们看到在SensorDevice.cpp中没有getInstance()方法的实现,所以我们可以看其父类,





在frameworks/base/services/sensorservice/SensorDevice.h中看到classSensorDevice
: public Singleton<SensorDevice>,发现父类是Singleton,这也是个模板类,它的基本功能就是实现一个唯一的对象,也就是单例模式。所以我们可以去看SensorDevice的构造函数。



在其中我们先来了解下两个变量structsensors_poll_device_t* mSensorDevice和structsensors_module_t*
mSensorModule。



该接口的定义实际上是对标准的硬件模块hw_module_t的一个扩展,增加了一个get_sensors_list函数,用于获取传感器的列表。



Sensor设备结构体sensors_poll_device_t,对标准硬件设备hw_device_t结构体的扩展,主要完成读取底层数据,并将数据存储在structsensors_poll_device_t结构体中,poll函数用来获取底层数据,调用时将被阻塞
其中我们可以通过SENSORS_HARDWARE_MODULE_ID和函数hw_get_module来获取到对mSensorModule的初始化。
如果mSensorModule成功初始化后,我们可以通过sensors_open(&mSensorModule->common,&mSensorDevice);对mSensorDevice初始化。



如果mSensorDevice初始化没有问题,我们就可以定义一个sensor_tconst*list;用来存放从mSensorModule->get_sensors_list()获取到了所有支持的sensors,并把这些sensors保存到mActivationCount中,并且通过mSensorDevice->activate()关闭sensors的功能。



对任意一个sensor设备都会有一个sensor_t结构体.
每个传感器的数据由sensors_event_t结构体表示.



四、Sensor的一般使用
1、通过上下文获取SensorManager的对象。
sensorManager= (SensorManager) Context.getSystemService(Context.SENSOR_SERVICE);
2、实例化一个你需要使用的sensor对象。
Sensorsensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
3、注册传感器
sensorManager.registerListener(this,sensor, SensorManager.SENSOR_DELAY_GAME);
4、实现传感器监听接口
public voidonSensorChanged(SensorEvent event)
public voidonAccuracyChanged(Sensor sensor, int accuracy)

5、反注册传感器
sensorManager.unregisterListener(this);
接下来就对上面的流程进行分析:
1、sensorManager= (SensorManager) Context.getSystemService(Context.SENSOR_SERVICE);
1.1、frameworks/base/core/java/android/content/Context.java中的getSystemService是抽象函数,需要找到实现的地方。实现的地方在frameworks/base/core/java/android/app/ContextImpl.java中的getSystemService中。





1.2、frameworks/base/core/java/android/app/ContextImpl.java调用了getSensorManager(),在其中mSensorManager=
newSensorManager(mMainThread.getHandler().getLooper());而这里的mMainThread其实就是ActivityThread,所以这里的mMainThread.getHandler().getLooper()就相当于获取到的Looper对象,也就是消息循环的队列。这样类中才可以创建Handler进行消息的发送处理。
1.3、接下来看下SensorManager的构造函数。frameworks/base/core/java/android/hardware/SensorManager.java的SensorManager(LoopermainLooper)。



1.3.1、首先调用了nativeClassInit(),这是通过jni调用初始化frameworks/base/core/jni/android_hardware_SensorManager.cpp中的对象gSensorOffsets。对应的就是frameworks/base/core/java/android/hardware/Sensor.java中的对象。



1.3.2、sRotation= sWindowManager.watchRotation()这里主要为了能够及时获取系统的rotation。
1.3.3、sensors_module_init();初始化sensor模块。JNI调用了frameworks/base/core/jni/android_hardware_SensorManager.cpp中的sensors_module_init(JNIEnv*env,
jclassclazz)。在函数中就调用了SensorManager::getInstance();也就是获取frameworks/base/libs/gui/SensorManager.cpp中的单例。根据代码可以发现getInstance()其实就是调用的父类Singleton的方法,其实最后还是看SensorManager.cpp的构造函数。在这个构造函数里其实就做了一件事:获取到sensorservice,并且通过getSensorList()获取到所有的sensors,并保存在mSensorList中。其中函数getSensorList()的实现在SensorService.cpp中,其实也就是返回了SensorService.cpp中的变量mSensorList,而这个变量是在启动sensorservice时初始化好了的。







1.3.4、接下来就是创建一个finalArrayList<Sensor> fullList =sFullSensorsList;,然后通过sensors_module_get_next_sensor()来获取每个sensor,并添加到sFullSensorsList中。
其中sensors_module_get_next_sensor()通过JNI调用frameworks/base/core/jni/android_hardware_SensorManager.cpp中的sensors_module_get_next_sensor(),在这个函数里主要就是把上面获取到所有sensors,转化成java里的Sensor对象。



1.3.5、最后就创建了一个线程:sSensorThread= new SensorThread();
2、Sensorsensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
这里面主要是获取到对应类型的sensors,并去第一个作为默认的senser。



3、sensorManager.registerListener(this,sensor, SensorManager.SENSOR_DELAY_GAME);
这里主要注册监听行为。



3.1、frameworks/base/core/java/android/hardware/SensorManager.java中的registerListener(SensorListenerlistener,
int sensors, intrate)。在这里面会根据类型逐一调用registerLegacyListener去注册匹配的类型。



3.2、frameworks/base/core/java/android/hardware/SensorManager.java中的registerLegacyListener(intlegacyType,
int type,SensorListener listener, int sensors, intrate)在里面首先会从mLegacyListenersMap搜索有没有当前activity对应的legacyListener,如果有则取出注册,如果没有则新建一个LegacyListener并添加到mLegacyListenersMap中去,然后再通过registerListener去注册。





其中LegacyListener它是SensorManager.java的内部类,它实现了SensorEventListener的方法。
3.3、frameworks/base/core/java/android/hardware/SensorManager.java中的registerListener(SensorEventListenerlistener,
Sensor sensor, int rate,Handlerhandler)。首先在sListeners中寻找是否有对应的ListenerDelegate对象,如果没有则新建一个ListenerDelegate对象,并且添加到sListeners中去。然后判断sListeners是否为空,如果为空,则直接返回false,如果不为空,则开启sSensorThread线程(sSensorThread.startLocked()),这个线程比较重要待会再细说。接下来就是通过enableSensorLocked(sensor,delay)去打开sensor。
3.4、frameworks/base/core/java/android/hardware/SensorManager.java中的sensors_enable_sensor()通过JNI调用frameworks/base/core/jni/android_hardware_SensorManager.cpp中的sensors_destroy_queue(JNIEnv*env,
jclass clazz, jintnativeQueue)在这里面通过调用frameworks/base/libs/gui/SensorEventQueue.cpp中的SensorEventQueue::enableSensor(),进而调用mSensorEventConnection->enableDisable(handle,true);这里通过binder调用到了frameworks/base/services/sensorservice/SensorService.cpp中的内部类SensorEventConnection中的方法enableDisable。进而调用了frameworks/base/services/sensorservice/SensorService.cpp的SensorService::enable方法。











3.5、在frameworks/base/services/sensorservice/SensorService.cpp中的enable方法中,首先根据handle找到对应的sensor,然后调用对应的activate()方法,这个函数的实现就在sensors.c中了。
如果打开的方法没有错误,则首先会在mActiveSensors中寻找是否会有对应的SensorRecord对象,这个类主要就是对SensorEventConnection的对象的处理。这里由于是第一次进来,所以肯定是没有的,所以会先newSensorRecord(connection);,然后在添加到mActiveSensors中,如果是虚拟设备,还需要添加到mActiveVirtualSensors中去。如果发现在mActiveSensors中找到了对应的对象则说明这个sensor已经打开了,我们需要添加到mConnections中,并且把上次的事件发送出去。
再接下来就是说明连接已经好了,就把sensor对应的handle添加到connection中,并把这个connection添加到mActiveConnections中去。

外传:sSensorThread= new SensorThread();



SensorThread是frameworks/base/core/java/android/hardware/SensorManager.java的内部类。其中有一个SensorThreadRunnable方法。在startLocked()中newthread()并把runnable作为对象传进去,然后start这个线程。然后看SensorThreadRunnable中的run方法,



a、首先调用了open()方法,而这里又调用了sensors_create_queue(),这里JNI调用了frameworks/base/core/jni/android_hardware_SensorManager.cpp中的sensors_create_queue()方法,在函数中先获得SensorManager的对象再调用它的createEventQueue()方法,而这里又调用了frameworks/base/libs/gui/SensorManager.cpp中的createEventQueue()。这里面是newSensorEventQueue(mSensorServer->createSensorEventConnection());,我们首先看下createSensorEventConnection()的实现,在frameworks/base/services/sensorservice/SensorService.cpp中的createSensorEventConnection()函数中就只是newSensorEventConnection(this),而在它的构造函数中是给了两个变量赋值,mService和mChannel=newSensorChannel()。
在SensorEventQueue的构造函数中SensorEventQueue发现就是把mSensorEventConnection赋值成返回的SensorEventConnection,并且在SensorEventQueue::onFirstRef()把mSensorChannel初始化为mSensorEventConnection->getSensorChannel();也就是mChannel,也就是SensorChannel().
这样消息队列就创建好了,并将返回值赋给sQueue。













b、接下来就进入了一个while的死循环。
b.1、首先通过sensors_data_poll(sQueue,values, status,timestamp)读取事件。JNI调用了frameworks/base/core/jni/android_hardware_SensorManager.cpp中的sensors_data_poll(JNIEnv*env,
jclass clazz, jint nativeQueue,jfloatArray values, jintArraystatus, jlongArraytimestamp)。这个函数中通过SensorEventQueue中read方法读取数据保存到ASensorEvent,再把值赋给传进来的参数。
frameworks/base/libs/gui/SensorEventQueue.cpp中的read其实是调用的frameworks/base/libs/gui/SensorChannel.cpp中的read方法。我们可以看下SensorChannel.cpp的构造函数,其实它就是创建了一管道。读取的这端对应的就是read方法,而写的这端对应的就是write方法,而哪里写数据的呢,其实就在frameworks/base/services/sensorservice/SensorService.cpp中的threadLoop()中的一个循环里。







b.2、再判断sensors_data_poll是否读取成功,并且sListeners是不是空的。如果是则做一些清理的处理。
b.3、再接下来取得Sensor对象,再取得对应的ListenerDelegate对象。然后调用ListenerDelegate的onSensorChangedLocked方法,在其中首先把变量存储到SensorEvent中去,然后创建一个Message。再由mHandler.sendMessage(msg);发送到队列中,由handleMessage处理。
首先根据类型,判断是否调用onAccuracyChanged()方法,mSensorEventListener就是传进来的activity对象。
然后再判断是否调用mSensorEventListener.onSensorChanged()方法。





4、在activity中实现SensorEventListener中的两个方法
public voidonSensorChanged(SensorEventevent)在activity中复写这个方法,就会能够接受到上面发送过来的对应sensor的消息,做自己相应的处理。
public voidonAccuracyChanged(Sensor sensor, intaccuracy)在activity中复写这个方法,它提供了你要引用的发生精度变化的Sensor对象,精度使用以下四个状态常量之一来代表的
SENSOR_STATUS_ACCURACY_LOW
SENSOR_STATUS_ACCURACY_MEDIUM
SENSOR_STATUS_ACCURACY_HIGH
SENSOR_STATUS_UNRELIABLE。
5、sensorManager.unregisterListener(this);取消注册。
一般来讲registerListener写在activity的onResume函数中,而unregisterListener写在activity的onPause函数中。
这里的unregisterListener流程和registerListener类似,就不做多余的分析了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: