views:

84

answers:

3

I am looking to create timed events which trigger UI changes (like a Toast) on Android. I already know you can do this with a Handler object's postDelayed(runnable, timeDelay) method (see this page for a great example).

Here is the twist: I also need to be able to pause and resume the countdown for these events. So when a user pauses the on-screen timer it also pauses the countdown before each of these events trigger.

One approach that came to mind was to create a Handler object on a new Thread (not the UI thread) and queue up my events using postDelayed; then I would pause or resume this entire Thread's execution using this method as needed. The main problem here is figuring out how to make the events run on the UI thread after they have been triggered.

The only other way I can think of would be to check every second that the timer ticks against a list of all my events (brute force) on the UI thread, which is very messy.

If anyone has any thoughts on this or solutions, that would be great!

+1  A: 
  1. To be able use a handler with your own thread you need to have a looper see this for an example
  2. To be able to run a command in UI Thread you can pass a Handler reference inside your own thread code to be able to post messages to it.
    Hope it helps
Nikolay Ivanov
Thanks! I didn't really look into the Looper class before, but it looks like it would be a possible solution.
mxrider
+2  A: 

If all events need to be paused the same amount of time, you could keep track of how much pause time accumulated and, on the handleMessage, re-post using another postDelayed with that delay time.

Some logic would need to be added to make sure you delay them all the proper amount. For example, if a new event was added into the queue while the game was paused, you wouldn't want to re-post it delayed by the entire pause amount.

You could combine your idea (a queue of events with desired start times). Update that start time when the pause ends. Use a single event that is "processQueue" - set it to only fire when you think the next event should happen. If the time the next event should happen is delayed due to a pause, you can remove the "processQueue" event and re-post it.

ydant
Yes, all of my events would be paused the same amount of time. Thanks for the helpful response! You have come up with what looks like a pretty elegant solution.
mxrider
A: 

Handler#removeCallbacks will let you un-schedule a posted Runnable. You can post it again later when you know the new time at which it should run.

adamp
Yeah, but I would have to know how much time was left on the original runnable to know what to re-post it as. That wouldn't really jive with the whole "fire and forget" idea too well.
mxrider