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 クラスの静的フィールドにしました。その効果は興味深いものでした - 記録が行われた 2 回目に、最初の結果が表示されました (ただし、1 回目ではありません)。これは、センサーデータが記録される前にプライマリスレッドが終了していることを意味していると思います-何らかのバッファリングの問題???

4

1 に答える 1

2

データが失われることはありませんThread.sleep()。プログラムが 5 秒間停止し (センサー収集を含む)、その後行が実行fingerprint.finish(); され、センサー収集が開始されるという問題があります。

したがって、プログラムがスリープしている間はセンサーデータが記録されていないため、呼び出すLog.d("Unregister", "gyro results size before unregister: "+gyroscopeResults.size());と取得されます。0

プログラムを期待どおりに動作させるためのいくつかの提案を次に示します。

5 秒間のデータを収集するには、 を使用できます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する継続的なセンサー ログが必要な場合は、使用する方が適切です(たとえば、ファイルへのログ記録や clear などArrayList) 。

于 2013-02-11T05:50:37.790 に答える