Мне нужно, чтобы в Android была запущена служба, которая время от времени сохраняет значение в базе данных. Как часто это зависит от предпочтений пользователя, а также от того, произошли ли другие события, которые могут составлять от 30 секунд или до 30 минут.
Это не то, что скрыто от пользователя, и фактически пользователь, вероятно, должен знать, что он работает. Таким образом, я думаю, что сервис переднего плана, вероятно, лучший подход.
У меня запущена служба переднего плана с TimerTask, которая вычисляет, как часто она должна срабатывать. Эта служба является «липкой», поэтому она должна оставаться на месте, и у нее мало ресурсов, и ОС должна через некоторое время запустить ее обратно.
Моя проблема в том, что TimerTask, кажется, перестает работать через некоторое время, когда приложение находится в фоновом режиме.
Вот мой сервис:
public class TimerService extends Service {
private static final String LOG_NAME = TimerService.class.getName();
private Timer timer;
private final Handler timerHandler = new Handler();
@Override
public void onCreate() {
super.onCreate();
Notification notification = new NotificationCompat.Builder(this, "MY_APP_CHANNEL_ID")
.setContentTitle("My Timer Service")
.setContentText("Background timer task")
.setSmallIcon(R.drawable.timer)
.build();
startForeground(1, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTimer();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
stopTimer();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void stopTimer() {
if (timer != null) {
timer.cancel();
timer = null;
}
}
private void startTimer() {
stopTimer();
timer = new Timer();
long frequency = // calculate frequency
long delay = // calculate delay
timer.scheduleAtFixedRate(new MyTimerTask(), delay, frequency);
}
private void saveToDatabase() {
// Save some stuff to the database...
if (some condition) {
// might need to reschedule timer delay and frequency.
startTimer();
}
}
private class MyTimerTask extends TimerTask {
@Override
public void run() {
timerHandler.post(new Runnable() {
@Override
public void run() {
onTimerFire();
}
});
}
private void onTimerFire() {
try {
saveToDatabase();
} catch (Exception e) {
Log.e(LOG_NAME, "Error in onTimerFire", e);
}
}
}
}
Должно ли это работать? IE я могу иметь простой Таймер в службе переднего плана, которая работает непрерывно, пока эта служба не остановлена? Если да, то есть ли ошибка в моем коде?
Я выбрал таймер, чтобы попытаться упростить его, мне когда-либо нужен был только один таймер, и я хотел, чтобы его можно было легко перепланировать. Я действительно понимаю, что могу попробовать Handler, ScheduledThreadPoolExecutor или даже AlarmManager. Я думал, что AlarmManager может быть излишним и истощать ресурсы, если он увольняет тонну. Не говоря уже о перепланировке.