3

我正在我的 Android 应用程序中收集数据,如下所示(这是一个精简版):

public class Main extends Activity {

    ...

    public void log5secs(){
        try {
            CollectData collectData = new CollectData(this);
            // collect data for five seconds in the background
            Thread.sleep(5000);
            Log.d("unregister", "gyro from Main: "+collectData.gyroscopeResults.size());
            fingerprint.finish();
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }        

}

public class CollectData implements SensorEventListener  {

    ArrayList<SensorEvent> gyroscopeResults = new ArrayList<SensorEvent>();

    public CollectData(Context context){
        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
        sensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void onSensorChanged(SensorEvent event) {
        gyroscopeResults.add(event); 
        Log.d("SensorChanged", "gyro results size: "+gyroscopeResults.size());
    }

    public void finish(){
        unregister();
    }

    private void unregister() {
        Log.d("Unregister", "gyro results size before unregister: "+gyroscopeResults.size());
        sensorManager.unregisterListener(this);
    }
}

因此,日志消息显示每次调用 onSensorChanged 事件时,ArrayList 的大小都会增加(在 5 秒内达到 26)。

但是,当从 Main 请求大小或由于调用 unregister() 时,ArrayList 的大小为零。在调试器中,我看不到它在哪里发生了变化。

我的数据怎么了???

我在 HTC Sensation XL 上运行它。

更新:获得更多信息!出于好奇,我将 ArrayList gyroscopeResults 设为 Main 类中的静态字段。效果很有趣 - 第二次录制完成,第一次的结果是可见的(但不是第一次)。我想这意味着主线程在传感器数据被记录之前就完成了——某种缓冲问题???

4

1 回答 1

2

您的数据没有丢失,问题在于Thread.sleep()程序暂停 5 秒(包括传感器收集),然后fingerprint.finish(); 在此之后执行该行,开始传感器收集。

所以当你打电话时Log.d("Unregister", "gyro results size before unregister: "+gyroscopeResults.size());你会得到0,因为在程序睡眠时没有记录传感器数据。

这里有一些建议可以让你的程序按预期工作

采集5 秒的数据,可以使用 a Timer(这里我是在 5 秒后取消定时器,但是你可以在清除 后继续采集ArrayList,以免内存不足)

final Timer timer = new Timer();
final CollectData collectData = new CollectData(MainActivity.this);

timer.schedule(new TimerTask() {
boolean started = false;
@Override
public void run() {
  if (!started) {
    Log.d("unregister", "BEFORE] gyro from Main: " + collectData.gyroscopeResults.size());
    started = true;
  } else {
    collectData.finish();
    Log.d("unregister", "AFTER] gyro from Main: " + collectData.gyroscopeResults.size());
    timer.cancel();
  }
    }
}, 0, 5000);

另一种解决方案,可能更简单,如果你想保留Thread.sleep()log5secs()在一个Thread

new Thread() {
    public void run() {
        log5secs();
    }
 }.start();

但是,如果您想要连续传感器记录,每 5 秒对数据执行一次操作(例如记录到文件和/或清除) ,则使用Timer会更合适ArrayList

于 2013-02-11T05:50:37.790 回答