jni層的傳感器主要是用于作為客戶端來訪問native的SensorService,更多的是連接的作用
入口是/frameworks/base/core/java/android/hardware/SystemSensorManager.java
看看構造函數(shù),nativeCreate主要用于創(chuàng)建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層的函數(shù)位于/frameworks/base/core/jni/android_hardware_SensorManager.cpp
注冊了java層與c層的對應關系,主要注冊了兩個java類SystemSensorManager,BaseEventQueue伏伐。最后會在c層調用到java層BaseEventQueue的dispatchSensorEvent完成傳感器數(shù)據(jù)傳遞帕翻。
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來注冊傳感器監(jiān)聽,主要是構建一個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層對應函數(shù)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層對應函數(shù)
static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
jobject eventQWeak, jobject msgQ, jfloatArray scratch, jstring packageName, jint mode) {
SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
ScopedUtfChars packageUtf(env, packageName);
String8 clientName(packageUtf.c_str());
sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));//創(chuàng)建binder通信
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak, scratch);//用于接收sensor事件
receiver->incStrong((void*)nativeInitSensorEventQueue);
return jlong(receiver.get());
}
SensorEventQueue被通知后泉蝌,會執(zhí)行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);
}