Android Sensor工作流程(一)
2013-01-14 01:26
344 查看
转自http://www.eoeandroid.com/forum.php?mod=viewthread&tid=71783
这里的 listener 是因为 sensor 状态变化要产生变化的控件
然后在控件里重载 on
SensorChanged 和 onAccuracyChanged 方法
Java代码:
public void onSensorChanged(int sensor, float[] values)
public void onAccuracyChanged(int sensor, int accuracy)
复制代码
SensorManager
Sensor 主体代码和流程在 frameworks/base/core/java/android/hardware/SensorManager.java 里面
1.registerListener 其实是调用 registerLegacyListener:
Java代码:
public boolean registerListener(SensorListener listener, int sensors, int rate) {
...
result = registerLegacyListener(...);
...
}
复制代码
2. registerLegacyListener 其实就是构造一个 LegacyListener 对象并将其加入 HashMap 中去
Java代码:
private boolean registerLegacyListener(int legacyType, int type,SensorListener listener, int sensors, int rate){
...
legacyListener = new LegacyListener(listener);
mLegacyListenersMap.put(listener, legacyListener);
LegacyListener> mLegacyListenersMap
...
}
复制代码
3. LegacyListener 做了 2 件事 一个是调用我们重载的那 2 个接口 还有一个就是将 sensor 的数据刷到我们的设备显示界面上去
Java代码:
private class LegacyListener implements SensorEventListener {
...
LegacyListener(SensorListener target) {
mTarget = target;
mSensors = 0;
}
public void onSensorChanged(SensorEvent event) {
...
mapSensorDataToWindow();
mTarget.onSensorChanged(...);
...
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
...
}
}
复制代码
代码最后是一些 native 方法:
Java代码:
private static native void nativeClassInit();//SensorManager 构造函数里调用
private static native int sensors_module_init();//SensorManager 构造函数里调用
private static native int sensors_module_get_next_sensor(Sensor sensor, intnext);//SensorManager 构造函数里调用
static native int sensors_data_init();//SensorThread 构造里调用
static native int sensors_data_uninit();//SensorThread 析构里调用
static native int sensors_data_open(FileDescriptor fd); //SensorThread 的 run()循环调用
static native int sensors_data_close();//SensorThread 的 run()循环调用
static native int sensors_data_poll(float[] values, int[] status, long[] timestamp);
//SensorThread的run()循环调用
复制代码
SensorManager 与 IsensorService 的关系 SensorManager 调用 IsensorService 其实只是调用了 service 的方法来控制 thread 是 Lock
Java代码:
void startLocked(ISensorService service) {
...
ParcelFileDescriptor fd = service.getDataChanel();
...
}
复制代码
或者打开
Java代码:
mSensorService.enableSensor(l, name, handle, delay);
复制代码
IsensorService 的实例是这么获得的
Java代码:
mSensorService = ISensorService.Stub.asInterface(ServiceManager.getService(Context.SENSOR_SERVICE));
复制代码
IsensorService 是通过 aidl 定义的
Java代码:
interface ISensorService{
ParcelFileDescriptor getDataChanel();
boolean enableSensor(IBinder listener, String name, int sensor, int enable);
}
复制代码
SensorService
Java代码:
class SensorService extends ISensorService.Stub {
...
}
复制代码
service 最终被 manager 调到走的是 android 的标准流程我们不 care,我们想知道的其实就是 enableSensor 的实现
Java代码:
if (enable == SENSOR_DISABLE) {
mBatteryStats.noteStopSensor(uid, sensor);
} else {
mBatteryStats.noteStartSensor(uid, sensor);
}
复制代码
看是不是能打开 sensor
Java代码:
if (enable!=SENSOR_DISABLE && !_sensors_control_activate(sensor, true)) {
Log.w(TAG, "could not enable sensor " + sensor);
return false;
}
复制代码
如果 sensor 打开了 我们要监听状态还要对外面报告状态变化
Java代码:
if (l == null && enable!=SENSOR_DISABLE) {
l = new Listener(binder);
binder.linkToDeath(l, 0);
mListeners.add(l);
mListeners.notify();
}
复制代码
如果 sensor 被关闭了 我们要取消监听并且告诉外面关闭了传感
Java代码:
if (enable != SENSOR_DISABLE) {
l.addSensor(sensor, enable);
} else {
l.removeSensor(sensor);
deactivateIfUnused(sensor);
if (l.mSensors == 0) {
mListeners.remove(l);
binder.unlinkToDeath(l, 0);
mListeners.notify();
}
}
复制代码
另外还有一些唤醒和设置延迟的动作
Java代码:
if (mListeners.size() == 0) {
_sensors_control_wake();
}
if (minDelay >= 0) {
_sensors_control_set_delay(minDelay);
}
复制代码
从上面可以看出来 对于底层而言只要知道上层怎么调用传感的接口就好 所以最关心的还是。我标绿的 native 方法 上层的传感流程其实比较简单 就是标准的 service 管理和 notify 流程
Java代码:
private static native int _sensors_control_init();
private static native ParcelFileDescriptor _sensors_control_open();
private static native boolean _sensors_control_activate(int sensor, boolean activate);
private static native int _sensors_control_set_delay(int ms);
private static native int _sensors_control_wake();
复制代码
native 方法
1. manager 部分
frameworks/base/core/jni/android_hardware_SensorManager.cpp先看一眼它的方法注册
Java代码:
static JNINativeMethod gMethods[] = {
{"nativeClassInit", "()V", (void*)nativeClassInit },
{"sensors_module_init","()I", (void*)sensors_module_init },
{"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",(void*)sensors_module_get_next_sensor },
{"sensors_data_init", "()I", (void*)sensors_data_init },
{"sensors_data_uninit", "()I", (void*)sensors_data_uninit },
{"sensors_data_open", "(Ljava/io/FileDescriptor;)I", (void*)sensors_data_open },
{"sensors_data_close", "()I", (void*)sensors_data_close },
{"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll },
};
复制代码
下面的是一个简单的例子:
Java代码:
sensors_data_open(JNIEnv *env, jclass clazz, jobject fdo){
jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
jfieldID offset = env->GetFieldID(FileDescriptor, "descriptor", "I");
int fd = env->GetIntField(fdo, offset);
return sSensorDevice->data_open(sSensorDevice, fd);
}
复制代码
调用到最后其实都是用的 sSensorDevice 的方法 static sensors_data_device_t* sSensorDevice = 0;
2.service 部分
frameworks/base/services/jni/com_android_server_SensorService.cpp先看一眼它的方法注册
Java代码:
static JNINativeMethod gMethods[] = {
{"_sensors_control_init", "()I", (void*) android_init },
{"_sensors_control_open", "()Landroid/os/ParcelFileDescriptor;", (void*) android_open },
{"_sensors_control_activate", "(IZ)Z", (void*) android_activate },
{"_sensors_control_wake", "()I", (void*) android_data_wake },
{"_sensors_control_set_delay","(I)I", (void*) android_set_delay },
};
复制代码
这里的 listener 是因为 sensor 状态变化要产生变化的控件
然后在控件里重载 on
SensorChanged 和 onAccuracyChanged 方法
Java代码:
public void onSensorChanged(int sensor, float[] values)
public void onAccuracyChanged(int sensor, int accuracy)
复制代码
SensorManager
Sensor 主体代码和流程在 frameworks/base/core/java/android/hardware/SensorManager.java 里面
1.registerListener 其实是调用 registerLegacyListener:
Java代码:
public boolean registerListener(SensorListener listener, int sensors, int rate) {
...
result = registerLegacyListener(...);
...
}
复制代码
2. registerLegacyListener 其实就是构造一个 LegacyListener 对象并将其加入 HashMap 中去
Java代码:
private boolean registerLegacyListener(int legacyType, int type,SensorListener listener, int sensors, int rate){
...
legacyListener = new LegacyListener(listener);
mLegacyListenersMap.put(listener, legacyListener);
LegacyListener> mLegacyListenersMap
...
}
复制代码
3. LegacyListener 做了 2 件事 一个是调用我们重载的那 2 个接口 还有一个就是将 sensor 的数据刷到我们的设备显示界面上去
Java代码:
private class LegacyListener implements SensorEventListener {
...
LegacyListener(SensorListener target) {
mTarget = target;
mSensors = 0;
}
public void onSensorChanged(SensorEvent event) {
...
mapSensorDataToWindow();
mTarget.onSensorChanged(...);
...
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
...
}
}
复制代码
代码最后是一些 native 方法:
Java代码:
private static native void nativeClassInit();//SensorManager 构造函数里调用
private static native int sensors_module_init();//SensorManager 构造函数里调用
private static native int sensors_module_get_next_sensor(Sensor sensor, intnext);//SensorManager 构造函数里调用
static native int sensors_data_init();//SensorThread 构造里调用
static native int sensors_data_uninit();//SensorThread 析构里调用
static native int sensors_data_open(FileDescriptor fd); //SensorThread 的 run()循环调用
static native int sensors_data_close();//SensorThread 的 run()循环调用
static native int sensors_data_poll(float[] values, int[] status, long[] timestamp);
//SensorThread的run()循环调用
复制代码
SensorManager 与 IsensorService 的关系 SensorManager 调用 IsensorService 其实只是调用了 service 的方法来控制 thread 是 Lock
Java代码:
void startLocked(ISensorService service) {
...
ParcelFileDescriptor fd = service.getDataChanel();
...
}
复制代码
或者打开
Java代码:
mSensorService.enableSensor(l, name, handle, delay);
复制代码
IsensorService 的实例是这么获得的
Java代码:
mSensorService = ISensorService.Stub.asInterface(ServiceManager.getService(Context.SENSOR_SERVICE));
复制代码
IsensorService 是通过 aidl 定义的
Java代码:
interface ISensorService{
ParcelFileDescriptor getDataChanel();
boolean enableSensor(IBinder listener, String name, int sensor, int enable);
}
复制代码
SensorService
Java代码:
class SensorService extends ISensorService.Stub {
...
}
复制代码
service 最终被 manager 调到走的是 android 的标准流程我们不 care,我们想知道的其实就是 enableSensor 的实现
Java代码:
if (enable == SENSOR_DISABLE) {
mBatteryStats.noteStopSensor(uid, sensor);
} else {
mBatteryStats.noteStartSensor(uid, sensor);
}
复制代码
看是不是能打开 sensor
Java代码:
if (enable!=SENSOR_DISABLE && !_sensors_control_activate(sensor, true)) {
Log.w(TAG, "could not enable sensor " + sensor);
return false;
}
复制代码
如果 sensor 打开了 我们要监听状态还要对外面报告状态变化
Java代码:
if (l == null && enable!=SENSOR_DISABLE) {
l = new Listener(binder);
binder.linkToDeath(l, 0);
mListeners.add(l);
mListeners.notify();
}
复制代码
如果 sensor 被关闭了 我们要取消监听并且告诉外面关闭了传感
Java代码:
if (enable != SENSOR_DISABLE) {
l.addSensor(sensor, enable);
} else {
l.removeSensor(sensor);
deactivateIfUnused(sensor);
if (l.mSensors == 0) {
mListeners.remove(l);
binder.unlinkToDeath(l, 0);
mListeners.notify();
}
}
复制代码
另外还有一些唤醒和设置延迟的动作
Java代码:
if (mListeners.size() == 0) {
_sensors_control_wake();
}
if (minDelay >= 0) {
_sensors_control_set_delay(minDelay);
}
复制代码
从上面可以看出来 对于底层而言只要知道上层怎么调用传感的接口就好 所以最关心的还是。我标绿的 native 方法 上层的传感流程其实比较简单 就是标准的 service 管理和 notify 流程
Java代码:
private static native int _sensors_control_init();
private static native ParcelFileDescriptor _sensors_control_open();
private static native boolean _sensors_control_activate(int sensor, boolean activate);
private static native int _sensors_control_set_delay(int ms);
private static native int _sensors_control_wake();
复制代码
native 方法
1. manager 部分
frameworks/base/core/jni/android_hardware_SensorManager.cpp先看一眼它的方法注册
Java代码:
static JNINativeMethod gMethods[] = {
{"nativeClassInit", "()V", (void*)nativeClassInit },
{"sensors_module_init","()I", (void*)sensors_module_init },
{"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",(void*)sensors_module_get_next_sensor },
{"sensors_data_init", "()I", (void*)sensors_data_init },
{"sensors_data_uninit", "()I", (void*)sensors_data_uninit },
{"sensors_data_open", "(Ljava/io/FileDescriptor;)I", (void*)sensors_data_open },
{"sensors_data_close", "()I", (void*)sensors_data_close },
{"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll },
};
复制代码
下面的是一个简单的例子:
Java代码:
sensors_data_open(JNIEnv *env, jclass clazz, jobject fdo){
jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
jfieldID offset = env->GetFieldID(FileDescriptor, "descriptor", "I");
int fd = env->GetIntField(fdo, offset);
return sSensorDevice->data_open(sSensorDevice, fd);
}
复制代码
调用到最后其实都是用的 sSensorDevice 的方法 static sensors_data_device_t* sSensorDevice = 0;
2.service 部分
frameworks/base/services/jni/com_android_server_SensorService.cpp先看一眼它的方法注册
Java代码:
static JNINativeMethod gMethods[] = {
{"_sensors_control_init", "()I", (void*) android_init },
{"_sensors_control_open", "()Landroid/os/ParcelFileDescriptor;", (void*) android_open },
{"_sensors_control_activate", "(IZ)Z", (void*) android_activate },
{"_sensors_control_wake", "()I", (void*) android_data_wake },
{"_sensors_control_set_delay","(I)I", (void*) android_set_delay },
};
复制代码
相关文章推荐
- Android4.2 G-Sensor工作流程
- android中Sensor 工作流程
- Android传感器Sensor工作流程
- android中Sensor 工作流程
- android中Sensor 工作流程
- android中Sensor 工作流程
- android中Sensor 工作流程
- Android 浅谈Sensor工作流程(一)
- Android4.2 G-Sensor工作流程
- Android 浅谈Sensor工作流程(二)
- <4>Android4.2 G-Sensor工作流程
- Android4.2 G-Sensor工作流程
- Android网络框架volley学习(二)工作流程分析
- android 4.0 蓝牙分析-设置面板中蓝牙工作的流程
- Android 7.0 WifiMonitor工作流程分析
- Android 4.4 Kitkat Phone工作流程浅析(四)__RILJ工作流程简析
- Android--Pin流程,飞行模式相关流程总结【工作日记一】
- Android 7.0 Vold工作流程
- Android中G-Sensor相关流程
- Android Wifi的工作流程