Dibujo de lienzo SurfaceView de Android con un hilo

Estoy experimentando con el dibujo en un lienzo usando un hilo para crear un motor de juego simple, pero estoy teniendo 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 la forma en que quiero que funcione, parece que la aplicación está cambiando entre dos lienzos y la adición de un círculo a cada lienzo para que obtenga un cambio entre dos lienzos cada segundo con el mismo número de círculos, pero en un lugar diferente En el lienzo.

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

Mi código se muestra a continuación, por lo que sólo utilizar un launchthread que utiliza un layoutfile que enlaza a la animación que inicia un hilo y dibuja un círculo en el lienzo cada segundo. (Puede ignorar el touchvent, no se utiliza todavía).

El proyecto existe de un lema 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 interna de Thread:

 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) { } } } } 

2 Solutions collect form web for “Dibujo de lienzo SurfaceView de Android con un hilo”

Parece que la aplicación está cambiando entre dos lienzos

Sí, así es como funciona. Se llama buffering doble y es necesario redibujar todo el marco cada vez :

El contenido de la superficie nunca se conserva entre unlockCanvas () y lockCanvas (), por esta razón, cada píxel dentro del área de la superficie debe ser escrito.

Así que necesitas esta línea canvas.drawColor(Color.BLACK) para que te descomente en tu código.

Y no debe llamar a Thread.sleep(1000) mientras el lienzo está bloqueado, esto causará el problema de hambre .

Parece que tienes este trabajo, pero acabo de notar un pequeño error que debo señalar.

Has llamado canvas.restore () sin llamar a canvas.save () de antemano. De la referencia de desarrollador de Android para Canvas: "Es un error llamar a restore () más veces que se llamó save ()".

No veo ninguna razón para llamar a canvas.save () en su caso, por lo tanto debe quitar la llamada a canvas.restore ().

  • Combinar lienzo y diseño (Android)
  • Cámara2 con un SurfaceView
  • SurfaceView vs TextureView para la cámara?
  • Cómo implementar doble toque para vista de superficie en android
  • Grabar un video de resolución cuadrada en android
  • ¿Creación de AlertDialog con métodos estáticos?
  • Cómo pausar y reanudar un subproceso de surfaceView
  • ¿Qué puedo hacer cuando el BufferQueue ha sido abandonado?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.