一个简单的注册流程图:
--调用registerListener()函数,实际调用抽象函数registerListenerImpl
--子类SystemSensorManager实现了registerListenerImpl
--如果有sensor事件,则JNI层android_hardware_SensorManager.cpp就调用dispatchSensorEvent()方法发送
--onSensorChanged()处理事件
SensorManager是一个抽象类,应用程序使用/监听Sensor都通过它。
public abstract class SensorManager {//抽象类 /** @hide */ protected static final String TAG = "SensorManager"; ... }
public boolean registerListener(SensorEventListener listener, Sensor sensor,//提供接口,给应用层注册监听器 int samplingPeriodUs, Handler handler) { int delay = getDelay(samplingPeriodUs); return registerListenerImpl(listener, sensor, delay, handler, 0, 0); } public void unregisterListener(SensorEventListener listener) {//提供接口,给应用层卸载监听器 if (listener == null) { return; } unregisterListenerImpl(listener, null); }
注册/听器函数registerListener(SensorEventListener,Sensor,int,int)
SensorEventListener是监听器对象,负责接收和处理SensorEvent的事件。Sensor是要监听的sensor,如TYPE_PROXIMITY类型的.
如果Sensor有数据上报,那么SensorEventListener监听器对象就会收到消息,里面的onSensorChanged()函数就负责处理。
public boolean requestTriggerSensor(TriggerEventListener listener, Sensor sensor) {//注册one-shot trigger类sensor return requestTriggerSensorImpl(listener, sensor); } public boolean cancelTriggerSensor(TriggerEventListener listener, Sensor sensor) { return cancelTriggerSensorImpl(listener, sensor, true); }r equestTriggerSensor/cancelTriggerSensor与上面的registerListener/unregisterListener一样注册/卸载监听器用的,
只不过,监听器收到事件后就自动disable,如果要继续监听,就要在事件处理函数里再次调用requestTriggerSensor。
//抽象方法,由子类实现 protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags); protected abstract void unregisterListenerImpl(SensorEventListener listener, Sensor sensor); protected abstract boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor); protected abstract boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, boolean disable);上面的注册/卸载函数最终都调用xxImpl(),它是一个抽象方法,须在子类中实现
protected abstract List<Sensor> getFullSensorList();//获取当前Sensor列表另外getFullSensorList()也是抽象方法,须子类实现,为什么这样呢?为什么有SensorManager这个抽象类,不把活全干完,非要定义几个抽象方法让子类实现尼,我个人认为android把高度相同性质的函数放在抽象类中实现,而把一些相当灵活又与navtive层有交互的函数定义为抽象方法是有好处的,充份体现了面向对象设计的精髓:类是各种具有相同性质对象的抽象。细读SensorManager.java,特别是注释,有些人看代码不看注释,非常不好,一下子就读fucking code会很痛苦,注释至少告诉我函数/类是干吗用的,对把握了解整个代码逻辑非常有好处。
了解SensorManager后,是不是很想知道,应用层应该怎么使用它?
案例:
DisplayPowerController需要监听proximity sensor。打电话,手挡住psensor灭屏,离开则亮屏。
首先--建立一个SensorEventListener监听器对象mProximitySensorListener
再次--实现事件处理函数onSensorChanged()。(SensorEventListener是一个接口类可以用implements实现接口,也可以new)
然后--把此监听器对象注册入SensorManager。
即mSensorManager.registerListener(mProximitySensorListener,mProximitySensor,SensorManager.SENSOR_DELAY_NORMAL,mHandler);
mProximitySensorListener是SensorEventListener监听器对象,而mProximitySensor是Sensor对象,类型是TYPE_PROXIMITY,祥见Sensor类。Sensor类定义了目前android支持的所有Sensor类型,像acc,mag,gyr就更不用说了,还支持hear rate心率计数,step count步数,ambient temperature环境温度,relative humidity相当湿度等等,Sensor类还为每个sensor类型规定了value的大小,一个Sensor对象就代表一个sensor,通过这个对象你可以指定sensor的类型,是否支持wakeup,事件发送的delay是多少,有兴趣的可以细读Sensor.java。
mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,//注册监听器 SensorManager.SENSOR_DELAY_NORMAL, mHandler); private final SensorEventListener mProximitySensorListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) {//SensorEvent事件处理 if (mProximitySensorEnabled) { final long time = SystemClock.uptimeMillis(); final float distance = event.values[0]; boolean positive = distance >= 0.0f && distance < mProximityThreshold; Slog.d(TAG, "mProximitySensorListener: " + positive + "distance: " + distance + "Threshold: " + mProximityThreshold); handleProximitySensorEvent(time, positive); } }
来到
SystemSensorManager类,这是SensorManager的子类,实现SensorManager的所有抽象方法
另外还定义了一些数据结构,用于管理监听器和事件
public class SystemSensorManager extends SensorManager { private static native void nativeClassInit(); private static native int nativeGetNextSensor(Sensor sensor, int next); private static boolean sSensorModuleInitialized = false; private static final Object sSensorModuleLock = new Object(); private static final ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>(); private static final SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>(); ... public SystemSensorManager(Context context, Looper mainLooper) { mMainLooper = mainLooper; mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion; synchronized(sSensorModuleLock) { if (!sSensorModuleInitialized) { sSensorModuleInitialized = true; nativeClassInit(); // initialize the sensor list final ArrayList<Sensor> fullList = sFullSensorsList; int i = 0; do { Sensor sensor = new Sensor(); i = nativeGetNextSensor(sensor, i); if (i>=0) { Log.d(TAG, "found sensor: " + sensor.getName() + ", handle=" + sensor.getHandle()); fullList.add(sensor); sHandleToSensor.append(sensor.getHandle(), sensor); } } while (i>0); } } }
构造函数
首先--得到Sdkversion,因为不同android版本/不同sensor类型所支持的数据value size 不一样,SensorEvent事件对象在构造时必须指定valuesize。Sensor类的静态函数getMaxLengthValuesArray()可以根据不同的sdkLevel和Sensor类型返回相应的valuesize。可参考SensorEvent.java,Sensor.java。
然后--nativeClassInit(),跑到sensor jni层android_hardware_SensorManager.cpp
static void nativeClassInit (JNIEnv *_env, jclass _this) { jclass sensorClass = _env->FindClass("android/hardware/Sensor"); SensorOffsets& sensorOffsets = gSensorOffsets; sensorOffsets.name = _env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;"); sensorOffsets.vendor = _env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;"); sensorOffsets.version = _env->GetFieldID(sensorClass, "mVersion", "I"); sensorOffsets.handle = _env->GetFieldID(sensorClass, "mHandle", "I"); sensorOffsets.type = _env->GetFieldID(sensorClass, "mType", "I"); sensorOffsets.range = _env->GetFieldID(sensorClass, "mMaxRange", "F"); sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F"); sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F"); sensorOffsets.minDelay = _env->GetFieldID(sensorClass, "mMinDelay", "I"); sensorOffsets.fifoReservedEventCount = _env->GetFieldID(sensorClass, "mFifoReservedEventCount", "I"); sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount", "I"); sensorOffsets.stringType = _env->GetFieldID(sensorClass, "mStringType", "Ljava/lang/String;"); sensorOffsets.requiredPermission = _env->GetFieldID(sensorClass, "mRequiredPermission", "Ljava/lang/String;"); sensorOffsets.maxDelay = _env->GetFieldID(sensorClass, "mMaxDelay", "I"); sensorOffsets.flags = _env->GetFieldID(sensorClass, "mFlags", "I"); }nativeClassInit函数得到Sensor Java类的引用,把Java类里的mName,mVersion在native层做变量映射,目的是后面在native层会初始化这些Java类里的变量。所以你可以从Sensor.java代码里看到,它的构造函数是空的。
最后--回到SystemSensorManager构造函数do 循环就是把设备里支持的sensor挂进来。
new Sensor()对象,调用nativeGetNextSensor(sensor,i)函数从0开始检索,如果找到一个sensor,就传进来的sensor java对象里的变量初始化一下,就是上面讲到的mName,mVersion等等,成功返回值>0。把sensor对象加入到sFullSensorsList中,同时也加入到稀疏列表sHandleToSensor中。sFullSensorsList是给getFullSensorList()函数用的,而SystemSensorManager真正用到的是sHandleToSensor。
下面是搜索到的sensor:
10181 01-01 04:41:40.415 2818 2905 D SensorManager: found sensor: lis3dh-accel, handle=1 10182 01-01 04:41:40.415 2818 2905 D SensorManager: found sensor: yas537-mag, handle=2 10183 01-01 04:41:40.415 2818 2905 D SensorManager: found sensor: ltr559-light, handle=3 10184 01-01 04:41:40.415 2818 2905 D SensorManager: found sensor: ltr559-proximity, handle=4 10185 01-01 04:41:40.415 2818 2905 D SensorManager: found sensor: yas537-orientation, handle=5
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) { // Invariants to preserve: // - one Looper per SensorEventListener // - one Looper per SensorEventQueue // We map SensorEventListener to a SensorEventQueue, which holds the looper synchronized (mSensorListeners) { SensorEventQueue queue = mSensorListeners.get(listener); if (queue == null) { Looper looper = (handler != null) ? handler.getLooper() : mMainLooper; queue = new SensorEventQueue(listener, looper, this); if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) { queue.dispose(); return false; } mSensorListeners.put(listener, queue); return true; } else { return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags); } } }SystemSensorManager为管理SensorEventListener,和SensorEvent。
private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners = new HashMap<SensorEventListener, SensorEventQueue>();用HashMap为SensorEventListener,SensorEventQueue做map
所以registerListenerImpl
首先--从mSensorListeners里查找listener对应的queue。如果NULL,就new一个SensorEventQueue对象queue,并把传进来的listener,sensor添加到queue。
然后--mSensorListeners.put(listener,queue)添加map。
unregisterListenerImpl反之。
requestTriggerSensorImpl/cancelTriggerSensorImpl类似,只不过用HashMap mTriggerListeners和TriggerEventQueue
private final HashMap<TriggerEventListener, TriggerEventQueue> mTriggerListeners = new HashMap<TriggerEventListener, TriggerEventQueue>();
TriggerEventQueue queue
那么SensorEvent事件如何派发的?
JNI code android_hardware_SensorManager.cpp通过调用SystemSensorManager的dispatchSensorEvent()函数完成。
// Called from native code. @SuppressWarnings("unused") @Override protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy, long timestamp) { final Sensor sensor = sHandleToSensor.get(handle); SensorEvent t = null; synchronized (mSensorsEvents) { t = mSensorsEvents.get(handle); } ... // Copy from the values array. System.arraycopy(values, 0, t.values, 0, t.values.length); t.timestamp = timestamp; t.accuracy = inAccuracy; t.sensor = sensor; // call onAccuracyChanged() only if the value changes final int accuracy = mSensorAccuracies.get(handle); if ((t.accuracy >= 0) && (accuracy != t.accuracy)) { mSensorAccuracies.put(handle, t.accuracy); mListener.onAccuracyChanged(t.sensor, t.accuracy); } mListener.onSensorChanged(t); }dispatchSensorEvent()函数
首先--通过handle从SystemSensorManager里的sHandleToSensor稀疏列表里找到Sensor对象sensor
final Sensor sensor = sHandleToSensor.get(handle);
通过handle从SensorEventQueue里的mSensorsEvents稀疏列表里找到SensorEvent事件对象t
t = mSensorsEvents.get(handle);
然后--从传进来的float[] values把数据copy到t中。
最后--以t做为参数,调用mListener.onSensorChanged(t),把事件发送出去。
mListener就是通过registerListenerImpl注册进来的,如本例中的mProximitySensorListener。
那么调用mListener.onSensorChanged(t)就是调用mProximitySensorListener.OnSensorChanged(SensorEvent event)
TriggerEvent的派发流程也是类似
protected void dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp) { final Sensor sensor = sHandleToSensor.get(handle); TriggerEvent t = null; synchronized (mTriggerEvents) { t = mTriggerEvents.get(handle); } ... // Copy from the values array. System.arraycopy(values, 0, t.values, 0, t.values.length); t.timestamp = timestamp; t.sensor = sensor; // A trigger sensor is auto disabled. So just clean up and don't call native // disable. mManager.cancelTriggerSensorImpl(mListener, sensor, false); mListener.onTrigger(t); }只不过是调用mListener.onTrigger(t)罢了,另外还调用了mManager.cancelTriggerSensorImpl(mListener,sensor,false)
这就是为什么是one-shot trigger sensor只触发一次的原因了。
在Java层已经对如果注册SensorEventListener,如何接收SensorEvent有了大概的了解。
后面打算分析JNI层,JNI层如何做为中间层,怎样把低层消息转发给Java的?