0

我正在构建一个应用程序,该应用程序需要在其中一个加速度传感器上具有高分辨率,但根本没有来自任何其他传感器的数据。所以,当我在听事件时,我正在做以下事情:

 mSensorManager.registerListener(this, mAccelerometer,
      SensorManager.SENSOR_DELAY_FASTEST);

问题是,每次传感器发生变化时都会触发该事件,并进行检查——浪费了大量的 CPU 时间,这些时间可以用于更好的事情。

有没有办法节省这个 CPU 时间?

4

4 回答 4

1

尝试另一个标志:

SENSOR_DELAY_FASTEST    //get sensor data as fast as possible
SENSOR_DELAY_GAME       //rate suitable for games
SENSOR_DELAY_NORMAL     //rate (default) suitable for screen orientation changes
SENSOR_DELAY_UI         //rate suitable for the user interface
于 2012-09-27T08:25:45.163 回答
1

从 API 3 开始,您可以注册单个传感器。使用下面的方法:

    try {
        sensorMgr = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);

        sensors = sensorMgr.getSensorList(Sensor.TYPE_ACCELEROMETER);
        if (sensors.size() > 0) sensorGrav = sensors.get(0);

        sensorMgr.registerListener(this, sensorGrav, SensorManager.SENSOR_DELAY_FASTEST);

    } catch (Exception ex1) {
        try {
            if (sensorMgr != null) {
                sensorMgr.unregisterListener(this, sensorGrav);
                sensorMgr = null;
            }
        } catch (Exception ex2) {
            ex2.printStackTrace();
        }
    }

并且仅在加速度传感器发生变化时才会调用侦听器。

祝你好运。

于 2012-10-11T14:54:37.277 回答
1

我不想为每个传感器调用一个函数,只为我感兴趣的那个

这就是 Android 的工作方式,但只有在您注册多个传感器时才会发生这种情况。如果您想读取多个传感器,您可以使用 aswitch-case过滤您最喜欢的传感器。

@Override
public void onSensorChanged(SensorEvent event) {
    synchronized (this){
        switch (event.sensor.getType()) {
            case Sensor.TYPE_ACCELEROMETER:
                //Do your magic here
                break;
            case Sensor.TYPE_MAGNETIC_FIELD:
                System.arraycopy(event.values, 0, magneticFieldValues, 0,
                        event.values.length);
                break;
        }
    }
}

有没有办法节省这个 CPU 时间?

你真的需要SENSOR_DELAY_FASTEST吗?您阅读的速度越快,您消耗电池的速度就越快。如果您更改了它,您将节省 CPU 时间,因为您不必像使用时那样多次读取传感器,SENSOR_DELAY_FASTEST也不会执行那么多次该onSensorChanged方法。

请记住,使用FASTEST, GAME, NORMAL or UI并不意味着发生更改时您获得数据的速度有多快。这意味着设备读取注册传感器的频率(无论值是否相同)并onSensorChanged在最后一个值与刚刚读取的值不同时执行该方法(两者都来自相同传感器)。

于 2012-10-12T07:32:31.430 回答
1

你只需要听一个传感器:

    sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
    accSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sensorManager.registerListener(this, accSensor, SensorManager.SENSOR_DELAY_GAME);

现在就性能而言,根据我的经验,即使最快也不会对性能产生重大影响,但需要记住一些细节。值到达时应立即转储到另一个线程中进行处理。在传感器线程中进行所有处理可能会影响未来样本的性能或交付时间。

将值从 SensorData 中复制出来,并且不要保留对值数组的引用。这些是固定池的一部分,以后可能会重复使用,您不希望在您的代码下更改这些。

如果您关心精度,则 SENSOR_DELAY_FASTEST 通常不适合。速度的代价是数据不稳定。以最快的速度将传感器数据转储到 lof,并将设备放在稳定的平面上。它仍然会倾倒大量样本,因为它认为有很多变化需要报告,而使用 SENSOR_DELAY_GAME 时,样本会减慢,因为没有什么要报告的,这是正确的。摩托罗拉是另一个故事,因为他们积极压制重复样本并将设备放在平坦的表面上会看到报告的样本数量变为 0。

于 2012-10-13T05:08:36.563 回答