I use this strategy, first declare Handler and Runnable this way:
private final Observable mObservable = new Observable(); private final static int TIME_STEP_MS = 5; private final Handler mHandler = new Handler(); private final Runnable mTimeManager = new Runnable() { public void run() { mObservable.notifyObservers(TIME_STEP_MS); mHandler.postDelayed(mTimeManager, TIME_STEP_MS); } };
Then, when I want to start my time manager, I just call mTimeManager.run () and it will start to periodically notify my Observer (previously added).
If for some reason you need to stop the timer or something that you just do:
mHandler.removeCallbacks(mTimeManager);
[EDIT - more complete code]
Well, than making it clearer, I first created a special Observable object, such as [this optional]:
private final Observable mObservable = new Observable() { public void notifyObservers() { setChanged(); super.notifyObservers(); }; @Override public void notifyObservers(Object data) { setChanged(); super.notifyObservers(data); }; };
the reason is that I cannot call setChanged () outside the Observable class - it is protected, if it has not changed, it does not notify the browser.
Other declarations are saved in the same way as shown above, now I need to run this TimeManager somewhere, my application is LiveWallpaper, and I do all the materials for rendering into a class that extends Thread , but you do not need that, I made a method for called resumeDrawing() , this one is called right after super.start(); in my @Override from public synchronized void start() from the Thread class, the method looks like this:
public void resumeDrawing() { if (!mTimeManagerRunning)
and it is dual:
public void pauseDrawing() { if (mTimeManagerRunning) { System.err.println("Pausing renderer."); mHandler.removeCallbacks(mTimeManager); mTimeManagerRunning = false; } else { System.err.println("Renderer already paused."); } }
Ok, now we can start and stop the time manager, but who is listening? No one! therefore, let add'em: In the constructor of my Renderer, I add an Observer to my mObservable object, one of them is Renderer itself, so my rendering extends Thread and implements Observer :
@Override // from Observer interface public void update(Observable arg0, Object arg1) { mElapsedMsRedraw += (Integer) arg1; if (mElapsedMsRedraw >= mDrawingMsPerFrame) { mElapsedMsRedraw = 0; drawEm(); // refresh the canvas and stuff } }
to add observers that you just do mObservable.addObserver(THE_OBJECT - Implements Observer)
you can see that I do not reprocess my material every time I am notified, because I use this TimeManager for others, and not just update the Canvas , like updating the position of objects that I want to draw just inside.
So, you need to slow down the drawing in order to change the way internal objects change during the passage, I mean your circles and points, etc., or you can use your time step, I recommend the first.
Was it clearer? Hope this helps.