My activity starts a service which runs a CountDownTimer. The timer sends broadcasts back to the activity as it counts down. The activity processes the broadcasts in the onReceive method of a BroadcastReceiver. All of this works fine.
My problem comes when the following events happen in this order:
When the app is resumed the service is no longer sending broadcasts, so the activity does not know how much time is left on the timer or if it's finished. This prevents the activity from updating the UI.
I've tried a dozen ways of dealing with this, and read through many Stack Overflow questions and answers, but I've yet to find a solution. I would think that there's a way to pick up a broadcast that was sent while the activity was not active, but I've yet to find a way.
For the record, here is my relevant Activity and Service code:
activity.java
// Start service
timerIntent.putExtra("totalLength", totalLength);
this.startService(timerIntent);
// ...
// BroadcastReceiver
private BroadcastReceiver br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getExtras() != null && inSession) {
session.setRemaining(intent.getExtras().getLong("millisUntilFinished"));
updateProgress();
}
}
};
// ...
// onResume
@Override
public void onResume() {
super.onResume();
registerReceiver(br, new IntentFilter(TimerService.COUNTDOWN_TS));
}
service.java
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
long length = intent.getExtras().getLong("totalLength");
countDownTimer = new CountDownTimer(length, 1000) {
@Override
public void onTick(long millisUntilFinished) {
timerServiceIntent.putExtra("millisUntilFinished", millisUntilFinished);
sendBroadcast(timerServiceIntent);
}
@Override
public void onFinish() {
}
};
countDownTimer.start();
return super.onStartCommand(intent, flags, startId);
}
What's the best way to process the broadcasts that the service sent while the activity was stopped?
Use the BroadcastReceiver to store the last request (SharedPreferences perhaps) it received and check it when the Activity starts.
Alternatively, instead of processing a countdown using broadcasts, just store the time that the countdown would end. The Activity can then handle the countdown all by itself as it knows when it should end. Using a service and broadcasts seem to be a little over-engineered for such a simple task.
Update: From the way you have described your task, I see you needing to handle 2 scenarios. This is how I would likely do it.
Assuming that "XYZ" is the service\intent\whatever starting the countdown and "ABC" is the Activity displaying the progress. (ABC and XYZ could be the same activity if that is what you wanted)
Requirements: When the countdown starts, I would make XYZ store the time that the countdown should end in SharedPreferences.
ABC is already running when the countdown starts. As Commonsware said, the Eventbus model is excellent for handling this scenario so long as XYZ and ABC are running in the same process. Just fire an event to read the preference value and count down to the specified time. If the user closes ABC and reopens it, Scenario 2 will kick in.
ABC is not running. Check in OnResume whether the countdown time has elapsed. If not, set up ABC to display the countdown again. If there is no countdown active, do something else.
If you also need to do something when the countdown has elapsed regardless of whether you have a UI active, then again Commonsware's suggestion of AlarmManager is perfect.
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句