我写了一个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?
答案 0 :(得分:0)
正如zapl所说:
一个方法在调用它的线程中执行,而不是在它所源的类中。
所以我现在使用了一条消息让我的线程需要一个新的校准。这对我来说很好。