@Jason:
This was going to be a comment, but it grew too big and it is a different [better] answer to the one I just gave.
I have changed my implementation using this method as described here
http://obviam.net/index.php/the-android-game-loop/
By employing the method described above means you should not need to sleep the OnTouch events.
Also don't forget to protect your game loop thread as mentioned here http://wonton-games.blogspot.com/2010/06/lunar-lander-resume-game-workaround.html
Also also keep in mind that Chris Pruett when writing Replica Island said he used 2 threads, one for the update() and the other for render() - both will have to be protected.
Chris does sleep his OnTouch with 16 milliseconds (60 fps) to cut back the events - so I would say its best to experiment if you still need to cut the events down - you need only touch the screen whilst stuff is happening to see if it lags and thus subsequently speeds up when let go.
For my needs currently I am using the same thread as I haven't progressed into OpenGL, I still use the canvas. But when I go OpenGL, it will be 2 threads, and each will be a complete class of its own.
Finally, I don't time my sprites by counting frames, I've wrapped them with a timer. I'll share my Class and show you how I call it. Bear in mind I am still new to Java so apologies for poor code.
package com.yourname.yourapplication;
//Used for doing something after a set time
public class TimeDo {
private int mRepeat = 0; //Stores the last wait period for the reset() later
private long mTime = 0; //The goal time of when its due
private boolean mFlagged = false; //Stop them getting a second true on a subsequent check
public TimeDo(int milliseconds) {
reset(milliseconds);
}
public TimeDo() {
this(0);
}
public void reset(int milliseconds) {
mRepeat = milliseconds;
mTime = System.currentTimeMillis() + milliseconds;
mFlagged = mRepeat==0; //ignore if zero
}
public void reset() { //Set it back to the delay used last time
reset(mRepeat);
}
public boolean check() {
if (mFlagged) //Assert: shouldn't really happen
return false;
mFlagged = System.currentTimeMillis() > mTime;
return mFlagged;
}
public boolean checkAndReset() {
if (check()) {
reset();
return true;
}
return false; //note mFlagged could be true here, so don't use it
}
}
And it is implemented thusly: -
public class Gem {
private TimeDo mMoveGem = new TimeDo(100); //move 10 times a second, 100ms
private int mX = 0;
private int mY = 0;
private int mMoveX = 3;
private int mMoveY = 4;
.
.
.
public void update() {
if (mMoveGem.checkAndReset()) {
mX += mMoveX;
mY += mMoveY;
.
.
}
}
public void render(Canvas canvas) {
//etc etc
.
.
}
}
Hope any of that helps!
Sorry if you have to rewrite lots of your application - I did.
Edit: That TimeDo class is not a postDelayed runnable, like an automatic alarm. If you don't check it no "event" will fire. You could get excited and have it create a runnable and pass it a callback method that resides within your class (think of an OnClick method) - but defeats the purpose of running an exclusive time-able update() thread that updates all your components.