Lienzo de SurfaceView para Android con un hilo.

Estoy experimentando dibujar en un lienzo usando un hilo para crear un motor de juego simple, pero tengo algunos problemas extraños que no puedo explicar. El propósito de este "juego" es dibujar un círculo cada segundo en el lienzo. Esto funciona, pero no de la forma en que quiero que funcione, parece que la aplicación está cambiando entre dos lonas y agregando un círculo a cada lienzo para que pueda cambiar entre dos lonas cada segundo con la misma cantidad de círculos pero en un lugar diferente en el lienzo.

No sé qué estoy haciendo mal, pero no estoy tan familiarizado con Treadding, ¿tiene algo que ver con la cantidad de núcleos que tiene mi dispositivo Android o algo así?

Mi código se muestra a continuación, así que solo uso un hilo de inicio que utiliza un archivo de diseño que enlaza con el hilo de animación que inicia un hilo y dibuja un círculo en el lienzo cada segundo. (Puedes ignorar el evento táctil, aún no se usa).

El proyecto existe fuera de un hilo de lanzamiento principal:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

que utiliza este archivo de diseño:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">     
        <com.androidtesting.AnimationView
            android:id="@+id/aview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>
</FrameLayout>

Y mi clase Surfaceview con una clase Thread interna:

class AnimationView extends SurfaceView implements SurfaceHolder.Callback {
    private boolean touched = false;
    private float touched_x, touched_y = 0;
    private Paint paint;
    private Canvas c;
    private Random random;
    private AnimationThread thread;

    public AnimationView(Context context, AttributeSet attrs) {
        super(context, attrs);

        SurfaceHolder holder = getHolder();
        holder.addCallback(this);

        thread = new AnimationThread(holder);
    }

    class AnimationThread extends Thread {
        private boolean mRun;       
        private SurfaceHolder mSurfaceHolder;        

        public AnimationThread(SurfaceHolder surfaceHolder) {
            mSurfaceHolder = surfaceHolder;
            paint = new Paint();
            paint.setARGB(255,255,255,255);
            paint.setTextSize(32);
        }

        @Override
        public void run() {
            while (mRun) {
                c = null;
                try {
                    c = mSurfaceHolder.lockCanvas(null);
                    synchronized (mSurfaceHolder) {                 
                        doDraw(c);
                        sleep(1000);
                    }
                } catch (Exception e) {                 
                    e.printStackTrace();
                }finally {
                    if (c != null) {
                        mSurfaceHolder.unlockCanvasAndPost(c);
                    }
                }
            }
        }

        private void doDraw(Canvas canvas) {
            //clear the canvas
            //canvas.drawColor(Color.BLACK);                        

            random = new Random();
            int w = canvas.getWidth();
            int h = canvas.getHeight();
            int x = random.nextInt(w-50); 
            int y = random.nextInt(h-50);
            int r = random.nextInt(255);
            int g = random.nextInt(255);
            int b = random.nextInt(255);
            int size = 20;
            canvas.drawCircle(x,y,size,paint);            
            canvas.restore();
        }
        public void setRunning(boolean b) {
            mRun = b;
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
           touched_x = event.getX();
           touched_y = event.getY();

           int action = event.getAction();

           switch(action){
                case MotionEvent.ACTION_DOWN:           
                    touched = true;
                    break;
                case MotionEvent.ACTION_MOVE:
                    touched = true;
                    break;        
                default:
                    touched = false;
                    break;
           }

           return true;
    }

    public void surfaceCreated(SurfaceHolder holder) {
        thread.setRunning(true);
        thread.start();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        thread.setRunning(false);
        while (retry) {
            try {
                thread.join();
                retry = false;
            } catch (InterruptedException e) {
            }
        }
    }
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta