[Gvsig_desarrolladores] gvSIG Movile - carga de imagenes en hilos

Javier Carrasco jcarrasco en prodevelop.es
Jue Jul 23 10:50:38 CEST 2009


Hola Ignacio,
Si se te cierra la aplicación debe estar produciéndose un error
que la máquina virtual no captura. Sin haber hecho ninguna prueba
me arriesgo a decir que es un problema de concurrencia. Es decir
puede que desde varios hilos se esté utilizando algún objeto que
no está preparado para ser compartido por varios hilos 
simultáneamente.

¿Has probado tanto con J9 como con PhoneME?

Supongo que tus PDA tampoco tendrán varios procesadores y como de 
cualquier forma las capas deben pintarse de abajo a arriba, te
recomiendo que pruebes a lanzar esos pintados en un solo hilo (o 
lanzar los hilos uno detrás de otro) y si eso resuelve el problema
puedes mirar qué objeto no soporta concurrencia.

Respecto a la mejora que esta técnica supone yo tengo una opinión 
personal algo distinta. En gvSIG desktop el pintado se realiza de 
la forma que tú estás implementando para mobile pero yo creo que 
el frecuente repintado que se realiza por el recentrado del GPS 
y la poca potencia de las PDA permite repensar esta técnica.

Desde mi punto de vista la técnica más correcta en este caso sería
aprovechar la imagen anterior (la última pintada) y ajustarla para 
mostrarla al usuario hasta que tengamos una que la sustituya. Por 
ejemplo, al hacer pan, la imagen anterior puede pintarse desplazada
hasta que tengamos una nueva (esto ya se hace a medias, y sirve para
el caso del recentrado del GPS) y al hacer zoom la imagen anterior 
puede escalarse y mostrarse hasta que tengamos la nueva (esto no está 
implementado aún). Esto suele costar menos (en tiempo de proceso) que
pintar alguna capa.

La técnica de desktop en mobile puede producir un parpadeo muy grande
ya que al moverse (por ejemplo con recentrado de GPS) la pantalla se 
queda blanca esperando la primera capa, luego sobre eso se pinta otra 
capa, etc. A mi modo de ver, la técnica de utilizar la imagen anterior 
permite mantener la referencia entre lo que estábamos viendo hace un 
momento y lo que se va a mostrar en el momento siguiente mientras que
usando la otra puede parecer que lo que se muestra es completamente 
nuevo.

De todas formas si terminas de implementarlo, por favor, cuéntanos qué
tal funciona.

Un saludo
Javi



-----Mensaje original-----
De: gvsig_desarrolladores-bounces en listserv.gva.es en nombre de Ignacio Gámez Ramírez
Enviado el: jue 23/07/2009 9:41
Para: Lista de Desarrolladores de gvSIG
Asunto: [Gvsig_desarrolladores] gvSIG Movile - carga de imagenes en hilos
 
Buenas,

Estoy haciendo algunas pruebas para cambiar la forma de renderizar las imágenes y tengo un problema con el que llevo varios días sin conseguir detectar cual es el error.
Os comento: En el MapControl se tiene el método "public boolean draw(boolean doClear)" que se encarga de renderizar las distintas capas a través de otro método de la clase MapContext. La forma de renderizar las capas es secuencial de forma que hasta que no se completa la carga de todas las capas no se muestra la imagen final. Yo estoy intentando que la renderización de capas se haga de forma independiente para que a medida que se carga una capa se muestre en el visor. Para ello he creado una clase "Render" que se encarga de lanzar la renderización de cada capa en un hilo (Thread) independiente y a medida que terminan de pintarse se le muestra al usuario (con orden).
A esta clase "render" le paso el gráfico del MapControl para pintar las capas en este. 
Os adjunto la clase Render para que os hagáis una idea (es una clase muy simple). Para dar transparencia a la imagen base he hecho una chapuza que es cargar una imagen transparente al cargar la aplicación para no perder tiempo en cargar la imagen cada vez que se utiliza (pero sin más, eso no preocupa ahora).

El problema que tengo es que en PC funciona correctamente (a medida que se pintan las imágenes se les va mostrando al usuario) pero en móvil se cierra inesperadamente la máquina virtual y después de revisar el código (que es muy simple) no consigo entender por qué puede ser. Me imagino que tiene que estar relacionado con pintar en el gráfico del MapControl de forma "aleatoria" o mejor dicho "no de forma secuencial". 

Me interesa mucho resolver esto porque creo que mejora la visualización de los mapas ya que cuando hay varias capas se evita que el usuario tenga que esperar mucho para ver resultados.

EL método de la clase MapControl sería algo así:

public boolean draw(boolean doClear) 
{
	boolean do_something = (project.getMapContext().getLayerCount() > 0);

	if (true) {	clearCanvas();}
	if (do_something) 
	{
		setProcessing(true);
		//project.getMapContext().draw(mapGraphics, canc);
		draw(mapGraphics, canc);
	}
	return do_something;
}

public void draw(Graphics2D g,Cancellable canc)
{
	ViewPort viewPort = getViewPort(); 
	if (viewPort.getAdjustedExtent() == null) {return;}

	// IMPORTANTE: EL NUEVO RENDER
	Render render = new Render(g,viewPort,this);
      FLayer[] vls = getVisibleLayers();
      render.draw(vls, canc);
        
      System.gc();
}

public void setProcessing(boolean isSplashVisible, boolean notRedraw, Graphics2D g)
{
	processingSplash.setVisible(isSplashVisible);
	dontRedraw=notRedraw;
}

Siento enviaros toda esta chapa pero igual a alguien le interesa el tema ya que creo que mejora la visualización de mapas.

Un saludo.



------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: http://listserv.gva.es/pipermail/gvsig_desarrolladores/attachments/20090723/470d3300/attachment.htm 


More information about the gvSIG_desarrolladores mailing list