【Android源码 栏目提醒】:以下是网学会员为您推荐的Android源码 -android有关sensor的源码总结 - 技术总结,希望本篇文章对您学习有所帮助。
android有关sensor的
源码总结 虽然这篇文章写得很差因为赶时间所以就匆匆忙忙地写出来自己作一个笔记。
但是我想对大家应该有一点帮助。
1、有关sensor在Java应用程序的编程以注册多个传感器为例这程序是我临时弄出来的可能有错 package com.sensors.acc import
android.app.Activity import
android.os.Bundle import
android.util.Log import
android.widget.TextView import
android.hardware.SensorManager import
android.hardware.Sensor import
android.hardware.SensorEvent import
android.hardware.SensorEventListener public class acc extends Activity float x y z SensorManager sensormanager null Sensor accSensor null Sensor lightSensor null Sensor proximitySensor null TextView accTextView null / Called when the activity is first created. / Override public void onCreateBundle savedInstanceState super.onCreatesavedInstanceState setContentViewR.layout.main sensormanager SensorManagergetSystemServiceSENSOR_SERVICE accSensor sensormanager.getDefaultSensorSensor.TYPE_ACCELEROMETER lightSensor sensormanager.getDefaultSensorSensor.TYPE_LIGHT proximitySensor sensormanager.getDefaultSensorSensor.TYPE_PROXIMITY accTextView TextViewfindViewByIdR.id.textview_name SensorEventListener lsn new SensorEventListener public void onSensorChangedSensorEvent e if e.sensor accSensor Log.dquotsensorquot quotfound acc sensorquot x e.valuesSensorManager.DATA_X y e.valuesSensorManager.DATA_Y z e.valuesSensorManager.DATA_Z accTextView.setTextquotx quot x quot ny quot y quot nz quot z else if e.sensor lightSensor Log.dquotsensorquot quotfound light sensorquot accTextView.setTextquotdata is quot e.values0 else if e.sensor proximitySensor Log.dquotsensorquot quotfound proximity sensorquot accTextView.setTextquotdistance is quot e.values0 public void onAccuracyChangedSensor s int accuracy Override protected void onResume super.onResume // register this class as a listener for the orientation and accelerometer sensors sensormanager.registerListenerlsn accSensor SensorManager.SENSOR_DELAY_NORMAL sensormanager.registerListenerlsn lightSensor SensorManager.SENSOR_DELAY_NORMAL sensormanager.registerListenerlsn proximitySensor SensorManager.SENSOR_DELAY_NORMAL // sensormanager.unregisterListenerlsn Override protected void onStop // unregister listener sensormanager.unregisterListenerlsn accSensor sensormanager.unregisterListenerlsn lightSensor sensormanager.unregisterListenerlsn proximitySensor super.onStop 在onCreate函数中调用getSystemServiceSENSOR_SERVICE初始化一个SensorManager实例为什么要用getSystemService函数而不直接用new SensorManager呢我们看此函数的实现在ApplicationContext.java中 if SENSOR_SERVICE.equalsname return getSensorManager 然后getSensorManager的实现 private SensorManager getSensorManager synchronized mSync if mSensorManager null mSensorManager new SensorManagermMainThread.getHandler.getLooper return mSensorManager 看到没有初始化SensorManager的时候需要mMainThread.getHandler.getLooper这个参数之个应该是用来传递消息用的在SensorManager类的构造函数中会把此参数传给类成员mMainLooper。
如果用new SensorManager就需要另外获取mainLooper参数传递进去。
2、在
android中跟sensor有关的一些文件有SensorManager.java位于frameworksbasecorejavaandroidhardware目录下SensorService.java位于frameworksbaseservicesjavacomandroidserver目录下
android_hardware_SensorManager.cpp位于frameworksbasecorejni目录下与SensorManager.java相对应com_
android_server_SensorService.cpp在frameworksbaseservicesjni目录下与SensorService.java相对应。
还有SystemServer.java文件HardwareLibhardwareIncludeHardware目录下的Sensor.h头文件。
另外我们需要根据Sensor.h实现自己的一个源文件一般取名为sensors_xxx.c或者sensors_xxx.cpp。
3、SensorManager类分析 有几个函数比较重要必须清晰理解它们的实现才能了解整个传感器系统的实现。
从而更好地去实现硬件抽象层的实现。
几个比较重要的函数有构造函数SensorManager registerListener和unregisterListener其中registerListener和unregisterListener有多个标志为 Deprecated的是过时的就不要看了。
1构造函数SensorManagerLooper mainLooper 这个函数首先获取得传感器系统服务并赋给类成员mSensorService mSensorService ISensorService.Stub.asInterface ServiceManager.getServiceContext.SENSOR_SERVICE 这里我要说一句就是关于这个传感器系统服务很多书上都说用getSystemService是获得传感器的系统服务而它返回的是SensorManager类型所以以为整个系统都是使用同一个SensorManager类的实例以为我们在任何地方使用的SensorManager实例都是同一个它们的公共成员是共享的。
但是经过这两天的分析这种说法是错误的。
其实每次调用getSystemService函数时都初始化一个新的SensorManager实例而这个SensorManager实例会在构造函数里通过取得传感器系统服务SensorService来实现对下层传感器的一些控制。
而这个SensorService才是系统的传感器服务说服务不如说它只是SensorService类的一个实例罢了。
它只在系统初始化时初始化一次。
Android中的系统服务机制应该跟传感器的都差不多一个样都是由不同的Manager调用下层相同的Service。
你可以列举其它的Manager。
那它是什么时候初始化呢它是系统初始化在SystemServer进程里创建的SystemServer是一个管理很多系统服务的进程我们转到SystemServer.的main函数里可以看到一直到调用int2函数它会创建一个ServerThread最终调用AdbSettingsObserver类的run函数在run函数里有这么有一句 // Sensor Service is needed by Window Manager so this goes first Log.iTAG quotSensor Servicequot ServiceManager.addServiceContext.SENSOR_SERVICE new SensorServicecontext 这里就创建SensorService实例了。
在创建这个实例时会在SensorService构造函数中调用jni函数 public SensorServiceContext context if localLOGV Log.dTAG quotSensorService startupquot _sensors_control_init 我们看_sensors_control_init对应的为 static jint
android_initJNIEnv env jclass clazz sensors_module_t module if hw_get_moduleSENSORS_HARDWARE_MODULE_ID const hw_module_tampmodule 0 if sensors_control_openampmodule-gtcommon ampsSensorDevice 0 const struct sensor_t list int count module-gtget_sensors_listmodule amplist return count return 0 它主要调用了sensor.h中的sensors_control_open static inline int sensors_control_openconst struct hw_module_t module struct sensors_control_device_t device return module-gtmethods-gtopenmodule SENSORS_HARDWARE_CONTROL struct hw_device_tdevice 之后在系统任何地方使用的都是这个SensorService实例。
最后run函数调用Looper.loop就进行消息循环等待了这就是SystemServer进程的消息服务了。
这才真正叫做系统服务嘛。
我们继续看SensorManager类的构造函数取得SensorService后 nativeClassInit 这是一个jni函数SensorManager类调用的jni函数都在com_
android_server_SensorService.cpp里我们看这函数 static void nativeClassInit JNIEnv _env jclass _this jclass sensorClass _env-gtFindClassquotandroid/hardware/Sensorquot SensorOffsetsamp sensorOffsets gSensorOffsets sensorOffsets.name _env-gtGetFieldIDsensorClass quotmNamequot quotLjava/lang/Stringquot sensorOffsets.vendor _env-gtGetFieldIDsensorClass quotmVendorquot quotLjava/lang/Stringquot sensorOffsets.version _env-gtGetFieldIDsensorClass quotmVersionquot quotIquot sensorOffsets.handle _env-gtGetFieldIDsensorClass quotmHandlequot quotIquot sensorOffsets.type _env-gtGetFieldIDsensorClass quotmTypequot quotIquot sensorOffsets.range _env-gtGetFieldIDsensorClass quotmMaxRangequot quotFquot sensorOffsets.resolution _env-gtGetFieldIDsensorClass quotmResolutionquotquotFquot sensorOffsets.power _env-gtGetFieldIDsensorClass quotmPowerquot quotFquot 这个函数只是获取和设置一些信息吧我们不关心。
接着 sensors_module_init 我们看这函数 static jint sensors_module_initJNIEnv env jclass clazz int err 0 sensors_module_t const module err hw_get_moduleSENSORS_HARDWARE_MODULE_ID const hw_module_t ampmodule if err 0 sSensorModule sensors_module_tmodule return err 它获取了sensor的模块信息并把它赋给sSensorModule全局变量之后传的modules参数都为这个。
接着在构造函数里 final ArrayList fullList sFullSensorsList int i 0 do Sensor sensor new Sensor i sensors_module_get_next_sensorsensor i if igt0 Log.dTAG quotfound sensor: quot sensor.getName quot handlequot sensor.getHandle sensor.setLegacyTypegetLegacySensorTypesensor.getType fullList.addsensor sHandleToSensor.appendsensor.getHandle sensor while igt0 这里主要是通过jni函数sensors_module_get_next_sensorsensor i获取传感器列表并把它加入自己的fullList列表中。
我们看sensors_module_get_next_sensor函数 static jint sensors_module_get_next_sensorJNIEnv env jobject clazz jobject sensor jint next if sSensorModule NULL return 0 SensorOffsetsamp sensorOffsets gSensorOffsets const struct sensor_t list int count sSensorModule-gtget_sensors_listsSensorModule amplist if next gt count return -1 list next jstring name env-gtNewStringUTFlist-gtname jstring vendor env-gtNewStringUTFlist-gtvendor env-gtSetObjectFieldsensor sensorOffsets.name name env-gtSetObjectFieldsensor sensorOffsets.vendor vendor env-gtSetIntFieldsensor sensorOffsets.version list-gtversion env-gtSetIntFieldsensor sensorOffsets.handle list-gthandle env-gtSetIntFieldsensor sensorOffsets.type list-gttype env-gtSetFloatFieldsensor sensorOffsets.range list-gtmaxRange env-gtSetFloatFieldsensor sensorOffsets.resolution list-gtresolution env-gtSetFloatFieldsensor sensorOffsets.power list-gtpower next return next 它主要是调用HAL层的get_sensors_list函数取得传感器列表信息。
接着在sensorManger构造函数最后 sSensorThread new SensorThread 创建一个SensorThread线程。
但并未运行但在SensorThread类的构造函数里会执行jni函数 sensors_data_init 我们看此函数static jint sensors_data_initJNIEnv env jclass clazz if sSensorModule NULL return -1 int err sensors_data_openampsSensorModule-gtcommon ampsSensorDevice return err 它调用了HAL层的sensors_data_open函数而这个函数位于sensor.h中它调用的是 static inline int sensors_data_openconst struct hw_module_t module struct sensors_data_device_t device return module-gtmethods-gtopenmodule SENSORS_HARDWARE_DATA struct hw_device_tdevice Modules-gtmethods-gtopen函数。
而在SensorThread类的析构函数finalize里会调用 sensors_data_uninit static jint sensors_data_uninitJNIEnv env jclass clazz int err 0 if sSensorDevice err sensors_data_closesSensorDevice if err 0 sSensorDevice 0 return err 在sensor.h里 static inline int sensors_data_closestruct sensors_data_device_t device return device-gtcommon.closeampdevice-gtcommon 那什么时候sSensorThread线程会运行呢我们在下面看registerListener函数。
2 public boolean registerListenerSensorEventListener listener Sensor sensor int rate return registerListenerlistener sensor rate null 它调用的是 public boolean registerListenerSensorEventListener listener Sensor sensor int rate Handler handler 在这函数中先验证rate然后检测注册的listener在不在本类的sListeners列表中。
for ListenerDelegate i : sListeners if i.getListener listener l i break 如果不在就申请一个listener并把它加入全局列表sListener中并调用mSensorService的enableSensor函数使能传感器这个enableSensor函数最终会调用HAL层的active函数和set_delay函数使用后然后判断sListener列表是否为空当然第一次为空时加入一个新的listener就不为空了此时就执行sSensorThread的startLocked运行sSensorThread线程了 l new ListenerDelegatelistener sensor handler result mSensorService.enableSensorl name handle delay if result sListeners.addl sListeners.notify if sListeners.isEmpty sSensorThread.startLockedmSensorService 另一方面如果注册的listener在sListeners列表中则先调用mSensorService的enableSensor函数使能传感器然后把注册的传感器加入到已存在的listener中。
result mSensorService.enableSensorl name handle delay if result l.addSensorsensor 接下来我们看看startLocked函数它在SensorThread中 void startLockedISensorService service try if mThread null Bundle dataChannel service.getDataChannel mThread new Threadnew SensorThreadRunnabledataChannel SensorThread.class.getName mThread.start catch RemoteException e Log.eTAG quotRemoteException in startLocked: quot e 第一次mThread为null然后它调用了service.getDataChannel函数此函数在SensorService类中主要调用了jni函数_sensors_control_open public Bundle getDataChannel throws RemoteException // synchronize so we do not require sensor HAL to be thread-safe. synchronizedmListeners return _sensors_control_open SensorService类中调用的jni函数主要都在com_
android_server_SensorService.cpp文件 中我们看一下这个函数 static jobject
android_openJNIEnv env jclass clazz native_handle_t handle sSensorDevice-gtopen_data_sourcesSensorDevice if handle return NULL // new Bundle jobject bundle env-gtNewObject gBundleOffsets.mClass gBundleOffsets.mConstructor if handle-gtnumFds gt 0 jobjectArray fdArray env-gtNewObjectArrayhandle-gtnumFds gParcelFileDescriptorOffsets.mClass NULL for int i 0 i lt handle-gtnumFds i // new FileDescriptor jobject fd env-gtNewObjectgFileDescriptorOffsets.mClass gFileDescriptorOffsets.mConstructor env-gtSetIntFieldfd gFileDescriptorOffsets.mDescriptor handle-gtdatai // new ParcelFileDescriptor jobject pfd env-gtNewObjectgParcelFileDescriptorOffsets.mClass gParcelFileDescriptorOffsets.mConstructor fd env-gtSetObjectArrayElementfdArray i pfd // bundle.putParcelableArrayquotfdsquot fdArray env-gtCallVoidMethodbundle gBundleOffsets.mPutParcelableArray env-gtNewStringUTFquotfdsquot fdArray if handle-gtnumInts gt 0 jintArray intArray env-gtNewIntArrayhandle-gtnumInts env-gtSetIntArrayRegionintArray 0 handle-gtnumInts amphandle-gtdatahandle-gtnumInts // bundle.putIntArrayquotintsquot intArray env-gtCallVoidMethodbundle gBundleOffsets.mPutIntArray env-gtNewStringUTFquotintsquot intArray // delete the file handle but dont close any fil.
上一篇:
Android系统属性
下一篇:
兰州市2010年