【发布时间】:2018-05-13 18:27:12
【问题描述】:
我需要有一个在 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 可能是矫枉过正,如果它正在发射大量资源会消耗资源。更不用说重新安排了。
【问题讨论】:
-
您的代码在设备休眠时不会运行。这是你的症状吗?
-
是的,这就是问题所在。为什么它不会在后台运行?服务以“startForeground”启动,这意味着即使应用程序在后台,服务也会继续在前台运行。
-
您找到解决方案了吗?
标签: android android-service android-timer