正确地从线程启动方法

时间:2015-11-14 14:34:51

标签: java android multithreading

我写了一个Android应用程序来测量y方向的加速度。传感器值由线程处理,以保持我的UI响应。

这是我的主题:

public class SensorThread extends Thread implements SensorEventListener {
private Context context;
private SensorManager sensorManager;
private Sensor accelerometer;
private long lastUpdate;
private long startTime;
private final float RC = 150.0f;
float accel_y_smoothed = 1000000f;
float raw_y = 0f;
private Handler handler;

public SensorThread(Context context, Handler handler) {
    this.context = context;
    this.handler = handler;
    sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
    accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
    startTime = System.currentTimeMillis();
    lastUpdate = System.currentTimeMillis();
}

public void run() {
}

@Override
public void onSensorChanged(SensorEvent event) {
    // Gather Sensor data

    raw_y = event.values[1];

    if (System.currentTimeMillis() - lastUpdate > 10) {

        // Filter Sensor data
        float timeInterval = System.currentTimeMillis() - lastUpdate;
        //plot_raw.addValue(accel_y, startTime - System.currentTimeMillis());

        float alpha = timeInterval / (RC + timeInterval);
        if (accel_y_smoothed == 1000000f) {
            accel_y_smoothed = raw_y;
        } else {
            accel_y_smoothed = alpha * raw_y + (1 - alpha) * accel_y_smoothed;
        }
        //plot.addValue(accel_y_smoothed, startTime - System.currentTimeMillis());
        lastUpdate = System.currentTimeMillis();
        Message message = handler.obtainMessage(0);
        Bundle bundle = new Bundle();
        bundle.putFloat("smoothed_y", accel_y_smoothed);
        bundle.putFloat("raw_y", raw_y);
        bundle.putLong("timestamp", startTime - System.currentTimeMillis());
        message.setData(bundle);
        handler.sendMessage(message);

    }
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

public void stopThread() {
    sensorManager.unregisterListener(this);
}

public void resumeThread() {
    sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
}

public void calibrate() {
    long startCalibrationTime = System.currentTimeMillis() + 500;
    ArrayList<Float> calibration_values = new ArrayList<Float>();
    long lastUpdateCalibration = 0;
    while (System.currentTimeMillis() - startCalibrationTime + 500 < 1000) {
        if (lastUpdateCalibration != lastUpdate) {
            calibration_values.add(raw_y);
        }
    }
    float mean = 0.0f;
    for (int i = 0; i < calibration_values.size(); i++) {
        mean += calibration_values.get(i);
    }
    mean = mean / calibration_values.size();
    Message message = handler.obtainMessage(1);
    Bundle bundle = new Bundle();
    bundle.putFloat("y_offset", mean);
    message.setData(bundle);
    handler.sendMessage(message);
}

}

现在我实施了一个calibrate()功能来测量手机静止在桌子上时的平均偏移量。问题是,当我从主线程调用此函数时,它会阻止UI。

sensorThread.calibrate();从我的sensorThread实例上的主线程调用,该主线程是在主要活动开始时创建的。

如何正确调用此函数以阻止我的UI?

1 个答案:

答案 0 :(得分:0)

正如zapl所说:

  

一个方法在调用它的线程中执行,而不是在它所源的类中。

所以我现在使用了一条消息让我的线程需要一个新的校准。这对我来说很好。