#android #multithreading #sensors
#Android #многопоточность #датчики
Вопрос:
Я пишу приложение, которое по расписанию запускает акселерометр каждые 15 секунд и запускает его через 10 секунд для извлечения данных датчика. Я запускаю акселерометр с помощью AlarmManager и продолжаю его работу с помощью wakelock, когда экран гаснет. Но я обнаружил, что иногда:
- Акселерометр не может извлекать данные через некоторые периоды. Я имею в виду, что он был запущен в соответствии с logcat, но нет никаких данных датчика, затем он закрывается и запускается снова без данных.
- Я не знаю, почему акселерометр больше не запускался через несколько периодов, а раньше все было в порядке. Я обнаружил, что logcat сообщает «у прослушивателя с binder android.os.BinderProxy не существует акселерометра». Я не знаю почему.
ниже приведен код ядра:
Activity.java
Intent intent = new Intent(getApplicationContext(),SensorService.class);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long curTime = Calendar.getInstance().getTimeInMillis();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, curTime, _intervalTime, pendingIntent);
SensorService.java
public void onStart(Intent intent, int startId) {
new Thread(new Runnable(){
public void run() {
// TODO Auto-generated method stub
wl.acquire();
Log.d(TAG,"I'm bright!");
try {
Thread.sleep(_delayClose);// kill self after _delayClose ms
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stopSelf();// SensorService.this.stopSelf()
}
}).start();
this.mSensorManager.registerListener( _sensorHandle,
accSensor,
sensorDelay)
}
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
this.mSensorManager.unregisterListener(_sensorHandle);
Log.d(TAG,"TIEM UP");
if(wl.isHeld())
{
wl.release();
}
}
Ответ №1:
Я предполагаю, что при такой частой регистрации и отмене регистрации sensor listener должны возникать значительные накладные расходы, плюс накладные расходы AlarmManager.
Учитывая, что вам так часто нужны данные с датчиков, как насчет того, чтобы просто зарегистрировать вашего слушателя и заставить его внутренне управлять, когда он должен и не должен делать что-то полезное с получаемыми образцами?
public class SensorSamplrActivity extends Activity {
private final static String TAG = "samplr";
private final static int SAMPLE_INTERVAL_SECS = 15;
private final static int SAMPLE_DURATION_SECS = 10;
private SensorManager mSensorManager;
private long whenToStartSample = System.currentTimeMillis();
private long whenToEndSample = System.currentTimeMillis() SAMPLE_DURATION_SECS;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_GAME);
}
private SensorEventListener mSensorListener = new SensorEventListener() {
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
long now = System.currentTimeMillis();
if (now < whenToStartSample){
// ignore the event amp; wait for next time to sample
Log.d(TAG,"ignoring events for " (whenToStartSample - now) "ms");
return;
}
if (whenToStartSample <= now amp;amp; whenToEndSample > now){
Log.d(TAG,"Do something with this event @ " now);
}
else {
// we've gone past whenToEndSample so reset timers
whenToStartSample = now (SAMPLE_INTERVAL_SECS * 1000);
whenToEndSample = whenToStartSample (SAMPLE_DURATION_SECS * 1000) ;
}
}
};
@Override
public void onDestroy(){
super.onDestroy();
mSensorManager.unregisterListener(mSensorListener);
}
}
Комментарии:
1. то есть вы имеете в виду, что AlarmManager может планировать не так, как я хочу? Скучно, что я не могу снова появиться, когда что-то идет не так. Поэтому я не могу гарантировать, сколько раз или после того, как что-то пошло не так. Но ваш совет должен быть полезен. Спасибо.
2. Кстати, вы знаете, что частота дискретизации датчика будет ниже даже на 0,5 Гц, когда телефон почти неподвижен? Я беспокоюсь о том, что это остановит себя с задержкой на несколько секунд.
3. Вопрос AlarmMgr: я не know…it просто кажется неудобным способом пероидальной выборки, и вы говорите, что это не работает, поэтому я предлагаю вам решить проблему по-другому. Что касается вопроса остановки: Если вы включите wakelock, он не остановится, и слушатель просто продолжит прослушивание и будет получать события по мере их возникновения.