Developing Frogtek

El blog del Departamento de Tecnología

Etiqueta: database

Frogtek libera PoisonFrog

Llevabamos un tiempo queriendo dar esta noticia. Es un gran honor para todo el equipo de Frogtek presentar PoisonFrog.

Nuestro producto requiere un acceso a la base de datos que sea muy configurable y adaptable a los cambios, así como abrir varias bases de datos desde la misma aplicación. Realmente Android no permite hacer esto como a nosotros nos gustaba. Así que desde hace ya mucho tiempo teníamos una librería interna para hacer estas tareas.

Por eso pensamos que sería de mucha utilidad devolver a la comunidad mucho del conocimiento que nosotros hemos adquirido de ella. Por eso hemos liberado esa librería bajo licencia Apache 2. El nombre surgió tras un gran debate interno en el que se propusieron infinidad de nombres. Las Poison Frog son ranas  que cumplen caracteristicas que creemos que son comunes con la librería y con Frogtek.

  • Son las reinas de su entorno por ser venenosas.
  • Son vistosas dado su color.
  • Hay varios colores (Portar la librería a más sistemas)
  • Viven en centroamérica y sudamérica, exactamente donde desplegamos nuestro producto, tiendatek.
  • Son ranas, igual que el nombre de nuestra empresa. Vamos a ayudar a la comunidad con un “leap frog” para ir de los “early 80’s to the XXI century in terms of database connection”.

Aquí os dejo la web del proyecto.

https://code.google.com/p/poisonfrog/

Por favor sentíos libres de comentar, commitear y criticar constructivamente.

También queremos dar las gracias a nuestra gran diseñadora Kristel Aranda por hacernos el diseño del logo.

¡Gracias!

Crear nuestros propios adapters para listados, y no morir en el scroll

Si no vienes del post introductorio, quizás te gustaría leerlo.

Tercera entrega de la optimización a la que fue sometida nuestra aplicación. Esta vez, tiene que ver con los listados de elementos; de muchos elementos, como puede ser el inventario de una tienda. Sirva como ejemplo práctico que solíamos crear nuestros propios adapters (extend BaseAdapter, todo sea dicho) muy alegremente, pero sólo al principio. Como buenos desarrolladores, copiábamos código del primer sitio que encontrábamos, sin fijarnos en lo óptimo que era. Y como buenos desarrolladores, repito, hacíamos las pruebas de nuestros propios adapters con 5 o 6 elementos para simular el inventario de una tienda.
¿Qué pasó? Cuando tuvimos nuestro primer tendero con ganas de inventariar toda su tienda, enseguida se nos vio el plumero. Una lista de 1200 (mil doscientos) elementos, con código copi-pegado y poco probado, tiene un 99% de posibilidades de ir más lenta, al hacer scroll, que el stand-up meeting de un lunes de resaca.

Como bien apuntó Francho en un comentario, una manera de ganar velocidad haciendo scroll es omitiendo los reiterados findViewById cada vez que hay que cambiar los valores del famoso convertView. En su lugar, debemos hacer uso de los tag que podemos asignar a las filas (rows) de nuestro listado. ¿A quién no le suenan las funciones setTag() y getTag()? Pues hace tiempo, a nosotros ni se nos pasaban por la cabeza. Luego de ver el magnífico video de la Google I/O 2009, Making your Android UI Fast and Efficient, hicimos una capillita en la oficina a Romain Guy. Merece la pena cada año ver los videos de la Google I/O…

Muy bien. Con esto que he nombrado arriba, tenemos solucionado una parte de nuestro problema; es decir: que cada vez que se haga scroll y haya que buscar los widgets cuyas propiedades han de cambiar, no se haga siempre mediante el findViewById(), si no que utilicemos los tags.
La otra parte del problema, venía al experimentar que aún habiendo mejorado la velocidad de scroll un poquito, no conseguíamos ese efecto de fluidez que una lista ha de tener. ¿Por qué? Muy sencillo: cada nueva fila que aparecía en el listado al hacer scroll contenía uno, o a veces más, widgets cuyo contenido era calculado en el mismo momento del getView(). A veces eran cálculos de sumas, fáciles. Otras veces eran consultas a la Base de Datos, lo cual nos estaba robando mili-segundos de muy alto precio al hacer que el scroll de tu aplicación sea fluido.

Por lo tanto, otro mandamiento que nos grabamos a fuego en la mente: No harás consultas a la Base de Datos en el getView() de tus propios adapters. Las consultas, se hacen antes del setAdapter() del ListView. Si no, arderás en el infierno de los developers.

Y ya, para rizar el rizo de la optimización de un listado y hacerlo más rápido que Usain Bolt: Dime cuál es la fuente de datos que alimenta tu Adapter, y te diré cuántos mili-segundos perderás en cada getView().
¿Por qué digo esto? Por que, como bien dijo Pedro en un post: hay que evitar a toda costa el trabajar con ArrayList de objetos propios en android. Reflection lo llaman, ¿no? Android y reflection no son buenos amigos.
Así que en lugar de acceder a los datos que poblarán nuestros ListView de manera limpia y con código legible, como puede ser un ArrayList, os recomendamos que uséis directamente el objeto Cursor devuelto por la Base de Datos. Sí: mucho más sucio el código, pero no veas lo rápido que va todo.

En resumen, hoy hemos visto:

  1. El ViewHolder para evitar millones de findViewById()
  2. No hacer consultas a la Base de Datos dentro de un getView()
  3. La fuente de datos de un Adapter, a ser posible, que sea un Cursor

¿Me olvido algo?