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.
- Anular onDraw () o draw ()?
- El video de la API de MediaCodec de Android se reproduce demasiado rápido
- Las pantallas parpadean y cambian de tamaño al iniciar la grabación de vídeo
- SurfaceView se retrasa si está en ScrollView
- Adición de vista de texto a la vista de superficie
¡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
- Android VideoView.setAlpha no funciona (Xoom con 3.0)
- SurfaceView onMeasure () no estableció la dimensión medida llamando setMeasuredDimension ()
- "La superficie ha sido liberada" dentro de "surfaceCreated"
- Android: graba y reproduce video en el mismo SurfaceView
- Ejecutar una tarea larga en glThread sin bloquear el hilo de la interfaz de usuario en Android
- Reinicio / Pausa del hilo en onResume / onPause
- Cómo capturar la imagen de CameraView personalizado en Android?
- ¿Es esto posible tener la opinión de la textura para la cámara en forma circular para el androide?
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
Heres una gran explicación y posible solución
http://android-coding.blogspot.ca/2012/01/flickering-problems-due-to-double.html
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
- Circle CI Automated para Android Project no pudo construir el archivo APK y no se instaló en el dispositivo
- Diferencia entre build.xml y project_name.xml