jni层的传感器主要是用于作为客户端来访问native的SensorService,更多的是连接的作用
入口是/frameworks/base/core/java/android/hardware/SystemSensorManager.java
看看构造函数,nativeCreate主要用于创建jni层的SensorManager,nativeClassInit用于获取jni层对java层sensor结构的映射,便于在jni层修改java层的变量,nativeGetSensorAtIndex用于填充java层的sensor结构。
public SystemSensorManager(Context context, Looper mainLooper) {
mMainLooper = mainLooper;
mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
mContext = context;
mNativeInstance = nativeCreate(context.getOpPackageName());
synchronized(mLock) {
if (!sSensorModuleInitialized) {
sSensorModuleInitialized = true;
nativeClassInit();
}
}
// initialize the sensor list
for (int index = 0;;++index) {
Sensor sensor = new Sensor();
if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
mFullSensorsList.add(sensor);
mHandleToSensor.append(sensor.getHandle(), sensor);
}
}
jni层的函数位于/frameworks/base/core/jni/android_hardware_SensorManager.cpp
注册了java层与c层的对应关系,主要注册了两个java类SystemSensorManager,BaseEventQueue。最后会在c层调用到java层BaseEventQueue的dispatchSensorEvent完成传感器数据传递。
int register_android_hardware_SensorManager(JNIEnv *env)
{
RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager",
gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));
RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager$BaseEventQueue",
gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));
gBaseEventQueueClassInfo.clazz = FindClassOrDie(env,
"android/hardware/SystemSensorManager$BaseEventQueue");
gBaseEventQueueClassInfo.dispatchSensorEvent = GetMethodIDOrDie(env,
gBaseEventQueueClassInfo.clazz, "dispatchSensorEvent", "(I[FIJ)V");
gBaseEventQueueClassInfo.dispatchFlushCompleteEvent = GetMethodIDOrDie(env,
gBaseEventQueueClassInfo.clazz, "dispatchFlushCompleteEvent", "(I)V");
return 0;
}
使用CallVoidMethod回调java层的dispatchSensorEvent方法
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchSensorEvent,
buffer[i].sensor,
mScratch,
status,
buffer[i].timestamp);
}
使用registerListenerImpl来注册传感器监听,主要是构建一个SensorEventQueue,当sensor事件来到是时候,SensorEventQueue会被通知到。
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
synchronized (mSensorListeners) {
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
final String fullClassName = listener.getClass().getEnclosingClass() != null ?
listener.getClass().getEnclosingClass().getName() :
listener.getClass().getName();
queue = new SensorEventQueue(listener, looper, this, fullClassName);
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener, queue);
return true;
} else {
return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
}
}
}
SensorEventQueue继承与BaseEventQueue,初始化是会新建一个binder connection与sensor service通信,nativeInitBaseEventQueue就是用于建立binder通信的。native层对应函数nativeInitSensorEventQueue
BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
if (packageName == null) packageName = "";
nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
new WeakReference<>(this), looper.getQueue(), mScratch,
packageName, mode, manager.mContext.getOpPackageName());
mCloseGuard.open("dispose");
mManager = manager;
}
//native层对应函数
static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
jobject eventQWeak, jobject msgQ, jfloatArray scratch, jstring packageName, jint mode) {
SensorManager* mgr = reinterpret_cast(sensorManager);
ScopedUtfChars packageUtf(env, packageName);
String8 clientName(packageUtf.c_str());
sp queue(mgr->createEventQueue(clientName, mode));//创建binder通信
sp messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
sp receiver = new Receiver(queue, messageQueue, eventQWeak, scratch);//用于接收sensor事件
receiver->incStrong((void*)nativeInitSensorEventQueue);
return jlong(receiver.get());
}
SensorEventQueue被通知后,会执行dispatchSensorEvent来处理传感器事件,最后会进入onSensorChanged进入处理,这就回到了应用中的onSensorChanged处理了。注意的是,一个listener只能对应一个SensorEventQueue。
protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
long timestamp) {
final Sensor sensor = mManager.mHandleToSensor.get(handle);
SensorEvent t = null;
synchronized (mSensorsEvents) {
t = mSensorsEvents.get(handle);
}
if (t == null) {
// This may happen if the client has unregistered and there are pending events in
// the queue waiting to be delivered. Ignore.
return;
}
// 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);
}