Я новичок в программировании Java для Android (на самом деле я новичок в общем компьютерном программировании). Я намеревался сделать SensorEventListener датчика акселерометра в потоке, отдельном от основного потока в Service. Метод onSencorChanged хорошо работает в отдельном потоке, однако вскоре после запуска службы возникает ошибка ANR. Хотя ANR происходит, если я не завершаю работу в момент возникновения ANR и не нажимаю «подождать», чтобы приложение продолжало работать, приложение работает хорошо, как я и предполагал. Меня долго пытались найти, как решить эту проблему, но я не могу, наконец, заставить мое приложение перестать возникать ANR.
Это мой код, использующий HandleThread.
public class SwingArmSensorService extends Service {
private SensorManager mSensorManager;
private Sensor mSensor;
private AccelerometerListenerInService listener;
private HandlerThread mSensorThread;
private Handler mSensorHandler;
private static SuperActivityUsingServiceMain activity;
private int mSteps;
private final String SWING_SENSOR_INTENT_STEP_DATA_NAME = "steps";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Looper.myLooper() == null) {
Looper.prepare();
}
mSensorThread = new HandlerThread("Sensor Thread", Thread.MAX_PRIORITY); //
mSensorThread.start(); //
mSensorHandler = new Handler(mSensorThread.getLooper());
listener = new AccelerometerListenerInService();
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(listener, mSensor, SensorManager.SENSOR_DELAY_NORMAL, mSensorHandler);
mSteps = intent.getIntExtra(SWING_SENSOR_INTENT_STEP_DATA_NAME, 0);
Looper.loop();
...
}
private class AccelerometerListenerInService implements SensorEventListener {
private Handler mainHandler;
private float previousY, currentY;
private float x, y, z;
private final float THRESHOLD = 10f;
public AccelerometerListenerInService() {
mainHandler = new Handler(Looper.getMainLooper());
}
@Override
public void onSensorChanged(SensorEvent event) {
x = event.values[0];
y = event.values[1];
z = event.values[2];
currentY = y;
if (Math.abs(currentY - previousY) > THRESHOLD) {
mSteps++;
// Handle UI at main thread here
mainHandler.post(new Runnable() {
@Override
public void run() {
activity.setTextView(mSteps);
}
});
}
previousY = y;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
}
}
Я намеревался показать вам только часть, связанную с вопросом о коде, но я впервые публикую вопрос о переполнении стека, поэтому, если мой код слишком длинный, извините.