SurfaceView parpadeo / desgarro

Estoy tratando de averiguar cómo solucionar mi problema. He leído http://groups.google.com/group/android-developers/browse_thread/thread/a2aac88a08cb56c2/b7dff4ba388cd664?lnk=gst&q=SurfaceView#b7dff4ba388cd664 qué tipo de respuestas a mi pregunta, pero hasta donde puedo decir, es Una suerte de "dura suerte". Así que aquí está mi problema:

Estoy usando SurfaceView de la manera normal (lock / unlockAndPost) para dibujar un mapa de bits de mi fondo de juego siempre que la superficie se cambia (por ejemplo, orientación, etc) y estoy procesando una serie de círculos en movimiento (hasta 30 con un radio de Aproximadamente 25.f). Los datos x, y para las posiciones de estos círculos provienen de un servidor y todo funciona bien. Todos los objetos de círculo se almacenan en una lista y su posición se actualiza teniendo cuidado de garantizar que esta actualización esté sincronizada. Sin embargo, cuando dibujo estos círculos en la pantalla (durante canvas.lock ()), la mayoría de las veces se procesan bien, pero de vez en cuando (por ejemplo, una vez cada pocos segundos) algunos de los círculos parecen desgarrarse o parpadear brevemente por un marco. El número de círculos siempre es constante, por lo que no es el problema y no hay modificaciones concurrentes en la lista de círculos (como he dicho, está sincronizado). Incluso he intentado dibujar todos estos círculos a un mapa de bits en cada bucle de render y dibujar ese mapa de bits al lienzo principal. Esto sólo parece afectar a la perfomance aún más (~ 13FPS en comparación con ~ 30FPS al dibujar círculos directamente a la lona principal). Lo siento si la información es un poco vagos chicos, (tratando de mantener la empresa feliz: p), pero me preguntaba si alguien podría darme una pista? O simplemente no tengo suerte. Debo señalar que los datos de posicionamiento procedentes del servidor son datos en tiempo real y es de vital importancia que el renderizado refleje estas posiciones en tiempo real.

¡Gracias por cualquier ayuda! Chris

EDITAR:

Lo suficientemente justo. Aquí está el run () del hilo de renderizado.

@Override public void run() { Canvas c; while (mRun) { c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { panel.onDraw(c); } } finally { if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } } 

Cosas bastante estándar (casi una copia de carbono de lander lunar: p)

 @Override public void surfaceCreated(SurfaceHolder holder) { mBackground= Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.RGB_565); screenOrientation = getResources().getConfiguration().orientation; if(thread.getState()== Thread.State.TERMINATED){ thread = new RenderThread(holder, this); thread.setRunning(true); thread.start(); }else { thread.setRunning(true); thread.start(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Canvas c = new Canvas(mField); c.drawARGB(255,0,144,0); backgroundDetails.renderOnPanel(c, this); screenOrientation = getResources().getConfiguration().orientation; } 

Bastante fácil de seguir, sólo vuelva a dibujar el mapa de bits de fondo si la orientación cambia e iniciar el hilo de renderizado.

 public void onDraw(Canvas canvas) { canvas.drawBitmap(mField,0,0,null); drawPositionBeans(canvas, this); } 

Y finalmente:

  public void onDraw(Canvas canvas, RadarView radarView) { float beanX=0, beanY=0; float radius = 25.0f; final List<PositionBean> copyOfList = Collections.synchronizedList(positionBeans.getPositionBeans()); synchronized(copyOfList){ try { for (final PositionBean pb : copyOfList) { if (panel.getOrientation() == Configuration.ORIENTATION_PORTRAIT) { beanX = (float)pb.getY()*(-1); beanY = (float)pb.getX(); } else { beanX = (float)pb.getY()*(-1); beanY = (float)pb.getX()*(-1); } mPaint.setARGB(255,pb.getRgbColor().getR(), pb.getRgbColor().getG(), pb.getRgbColor().getB()); panel.drawSpot(canvas, beanX, beanY, radius, mPaint); mPaint.setStyle(Paint.Style.STROKE); mPaint.setARGB(255,255,222,1); for (int j = 0; j < selectedBean.size(); ++j) { if(pb.getTrack()==selectedBean.get(j)) { panel.drawSpot(canvas, beanX, beanY, radius+1, mPaint); } } mPaint.setStyle(Paint.Style.FILL); } } catch(Exception e) { Log.e("render", "Exception Drawing Beans: " + e); } } } 

Gracias de nuevo chicos. Chris

Está sucediendo becasue los gráficos del androide tiene una superficie del búfer y una superficie visible y cerciorarse de que estén siempre disponibles que suplen simplemente. Lo que significa que si dibuja en un fotograma no estará allí el siguiente a menos que lo dibuje en cada fotograma.

http://groups.google.com/group/android-developers/msg/8d1243c33f9b7b6e?pli=1

Tuve ese problema. La solución adecuada para mí es la sincronización del método onDraw y el método que actualiza la matriz de transformación. Porque había marcos cuando la matriz es idéntica (valor inicial de la nueva Matrix ()) y en el siguiente cuadro tenía valores correctos.

Me pareció después de leer un poco sobre la vista de la superficie que si llamas

 getHolder().lockCanvas(); 

Necesitas dibujar todo de nuevo.

A menos que usted proporcione su área sucia.

 getHolder().lockCanvas(Rect dirty); 

Si sólo desea volver a dibujar el área definida por el Rect

  • Cámara Android: la vista previa se amplía al grabar vídeo
  • Cómo reproducir varios archivos de video simultáneamente en un diseño lado a lado en diferentes vistas en Android
  • End SurfaceView y GameThread al salir de la aplicación
  • El nuevo procesamiento de gms.maps.MapView se retrasa un poco cuando está en un ListView?
  • Android SurfaceView no muestra onDraw
  • Haga un SurfaceView más grande que la pantalla (Ajuste de una vista previa de cámara a un SurfaceView más grande que la pantalla)
  • Crash con SurfaceView en Android NDK al pausar / reanudar la aplicación rápidamente
  • Cómo hacer que una clase que extiende SurfaceView iniciar una actividad?
  • Android: problema SurfaceView (anchura, altura)
  • Fragmentos - El niño especificado ya tiene un padre. Debe llamar a removeView () en el padre del niño primero
  • Cómo tomar una captura de pantalla de SurfaceView con una vista previa de la cámara
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.