一个简单的注册流程图:
--调用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);
}
requestTriggerSensor/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
来到registerListenerImpl实现函数
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
注册流程已经跑完,那么应用层的事件处理函数onSensorChanged() / onTrigger()就等着接收SensorEvent事件了。
那么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的?