Solución de almacenamiento en caché de imágenes local para Android: Square Picasso, Universal Image Loader, Glide, Fresco?

89

Estoy buscando una biblioteca de almacenamiento en caché y carga de imágenes asincrónicas en Android. Iba a usar Picasso, pero descubrí que Universal Image Loader es más popular en GitHub. ¿Alguien sabe acerca de estas dos bibliotecas? Un resumen de los pros y los contras sería genial.

(Todas mis imágenes están en disco localmente, por lo que no necesito redes, por lo tanto, no creo que Volley sea adecuado)

XY
fuente

Respuestas:

80

Actualización de septiembre de 2018: después de varios años, necesitaba casi lo mismo para una solución de almacenamiento en caché de imágenes local. Esta vez, UIL no ha estado en desarrollo activo. Comparé las bibliotecas populares y la conclusión es bastante obvia: solo usa Glide. Es mucho más potente y configurable. Hace años tuve que bifurcar y hacer cambios en UIL. Glide es compatible con todos mis casos de uso en términos de estrategia de almacenamiento en caché y múltiples niveles de resolución de almacenamiento en caché con claves personalizadas. ¡Solo usa Glide!

La comparación de Koushik Dutta es principalmente para el punto de referencia de velocidad. Su publicación solo tocó cosas muy básicas y no es específica para imágenes locales. Me gustaría compartir mis experiencias con Picasso y UIL después de hacer la pregunta. Tanto Picasso como UIL pueden cargar imágenes locales. Primero probé Picasso y estaba feliz, pero luego decidí cambiarme a UIL para tener más opciones de personalización.

Picasso:

  • La fluida interfaz de Picasso es agradable. Pero saltando con "with", "into", "load", en realidad no sabes qué hay detrás de la escena. Es confuso lo que se devuelve.

  • Picasso le permite especificar el tamaño exacto del objetivo. Es útil cuando tiene presión de memoria o problemas de rendimiento, puede cambiar algo de calidad de imagen por velocidad.

  • Las imágenes se almacenan en caché con el tamaño en su clave, es útil cuando muestra imágenes con diferentes tamaños.

  • Puede personalizar el tamaño de la memoria caché. Pero su caché de disco es solo para solicitudes http. Para las imágenes locales, si le importa la velocidad de carga, es bueno tener un caché de disco de miniaturas para no tener que leer varios MB para una imagen cada vez. Picasso no tiene este mecanismo para cambiar el tamaño y guardar miniaturas en el disco.

  • Picasso no expone el acceso a su instancia de caché. (Puede obtenerlo cuando configure Picasso por primera vez y conservarlo ...).

  • A veces, desea leer de forma asincrónica la imagen en un mapa de bits devuelto por un oyente. Sorprendentemente, Picasso no tiene eso. La dosis "fetch ()" no devuelve nada. "get ()" es para leer sincrónicamente, y "load ()" es para dibujar una vista de forma asincrónica.

  • Picasso solo tiene algunos ejemplos simples en la página de inicio, y tendrás que leer el javadoc desordenado para usos avanzados.

UIL:

  • UIL utiliza constructores para la personalización. Casi todo se puede configurar.

  • UIL no le permite especificar el tamaño que desea cargar en una vista. Utiliza algunas reglas basadas en el tamaño de la vista. No es tan flexible como Picasso. No tengo forma de cargar una imagen de menor resolución para reducir la huella de memoria. (Editar: este comportamiento se puede modificar fácilmente agregando un argumento ImageSize en el código fuente y omitiendo la verificación del tamaño de la vista)

  • UIL proporciona caché de disco personalizable, puede usar esto para almacenar en caché las miniaturas con el tamaño especificado. Pero no es perfecto. Aquí están los detalles . (Editar: si le importa la velocidad y desea múltiples niveles de almacenamiento en caché de miniaturas, como en mi caso, puede modificar el código fuente, dejar que la caché del disco use "memoryKey" y que también sea sensible al tamaño)

  • UIL por defecto almacena en caché imágenes de diferentes tamaños en la memoria, y se puede desactivar en la configuración.

  • UIL expone la memoria de respaldo y el caché de disco a los que puede acceder.

  • UIL proporciona formas flexibles de obtener un mapa de bits o cargarlo en una vista.

  • UIL es mejor en documentación. UIL brinda los usos detallados en la página de Github, y hay un tutorial vinculado.

Sugiero comenzar con Picasso, si necesita más control y personalización, elija UIL.

XY
fuente
De hecho, estoy atrapado entre ambos ... Básicamente, voy a recuperar imágenes de mi servidor almacenadas en un directorio allí ... así que a través de llamadas http y luego almacenarlas para almacenarlas en caché (miniatura y tamaño normal, probablemente las almacenaré ambos tamaños en mi directorio) ... ¿es picasso el camino a seguir entonces?
Lion789
@ Lion789 Picasso solo hace caché de memoria local para archivos locales, y usa HttpResponseCache para caché de disco de red, tienes que investigar eso. UIL tiene caché de disco configurable, puede hacer algunos pequeños cambios para que acepte diferentes tamaños de imagen / miniaturas. Tal vez pruebe Picasso primero, si lo encuentra demasiado limitado, elija UIL y personalícelo
XY
¡Entonces Picasso puede cargar imágenes más pequeñas! ¡Entonces no tengo que cargar los de 8 megapíxeles! ¡Gracias, me ayudaste!
Aron Lorincz
¿Puede responder esta pregunta? stackoverflow.com/questions/35433895/…
Usman Rana
UIL does not allow you to specify the size you want to load into a viewno es 100% correcto ... con UIL puede usarpublic void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageSize targetSize, ImageLoadingListener listener, ImageLoadingProgressListener progressListener)
Martin Mlostek
72

Si lees esta publicación en G + de Koush obtendrás soluciones claras para tus confusiones, he puesto el resumen de eso, ¡en que Android-Universal-Image-Loader es el ganador para tu requerimiento!

  • ¡Picasso tiene la mejor API de imágenes si estás usando la red!

  • UrlImageViewHelper + AndroidAsync es el más rápido. Sin embargo, jugar con estas otras dos grandes bibliotecas realmente ha puesto de relieve que la API de imágenes está bastante anticuada.

  • La volea es resbaladiza; Realmente disfruto de sus transportes de backend conectables,
    y puedo terminar colocando AndroidAsync allí. La
    gestión deprioridady cancelación desolicitudeses excelente (si está utilizando la red)

  • Android-Universal-Image-Loader es el más popular que existe
    actualmente. Altamente personalizable.

Este proyecto tiene como objetivo proporcionar un instrumento reutilizable para la carga, el almacenamiento en caché y la visualización de imágenes asincrónicas. Se basa originalmente en el proyecto de Fedor Vlasov y se ha refactorizado y mejorado enormemente desde entonces.

Próximos cambios en la nueva versión de UIL (1.9.2):

Posibilidad de llamar a ImageLoader desde el hilo de la interfaz de usuario Nueva API de caché de disco (más flexible). Nuevo LruDiscCache basado en DiskLruCache de Jake Wharton.

¡Teniendo en cuenta todo este Android-Universal-Image-Loader se adapta a sus requisitos ( cargar las imágenes en el disco localmente )!

LOG_TAG
fuente
Empecé con Picasso y terminé cambiándome a Universal, a pesar de tener todo completamente implementado. Picasso tiene una mejor interfaz de API pero también tiene muchos problemas. Este fue el último clavo en el ataúd.
Lisandro
45

Me gustaría compartir mi experiencia con estas 3 bibliotecas: UIL, Picasso y Volley. Anteriormente usé UIL, pero luego llegué a la conclusión de que realmente no puedo recomendarlo y sugeriría usar Volley o Picasso en su lugar, ambos desarrollados por equipos de gran talento. UIL no está nada mal, pero carece de la atención al detalle de las otras dos bibliotecas.

Encontré que UIL es menos agradable con el rendimiento de la interfaz de usuario; tiende a bloquear el hilo de la interfaz de usuario más que Volley o Picasso. Esto puede deberse en parte al hecho de que UIL no admite el procesamiento por lotes de las respuestas de imagen, mientras que Picasso y Volley lo hacen de forma predeterminada.

Además, no me gustó el sistema de caché en disco de UIL. Si bien puede elegir entre varias implementaciones, debo señalar que por el momento no hay forma de limitar la memoria caché del disco UIL tanto por tamaño total como por tiempo de vencimiento de la entidad. Volley y Picasso hacen eso, y usan el tiempo de vencimiento devuelto por el servidor de forma predeterminada, mientras que UIL lo ignora.

Finalmente, UIL le permite establecer una configuración de cargador de imágenes global que incluye la caché de disco seleccionada y las implementaciones y configuraciones de caché de memoria y otros detalles, pero esta configuración se aplicará en todas partes de su aplicación. Por lo tanto, si necesita más flexibilidad, como dos cachés de disco separados, no hay opción para UIL. Volley, por otro lado, le permite tener tantos cargadores de imágenes independientes como desee, cada uno con su propia configuración. Picasso utiliza una instancia global de forma predeterminada, pero también le permite crear instancias configurables por separado.

En resumen: Picasso tiene la mejor API, pero utiliza la caché de disco HTTP global compartida entre todas las HttpURLConnectioninstancias, lo que puede ser demasiado restrictivo en algunos casos. Volley tiene el mejor rendimiento y modularidad, pero es menos fácil de usar y requerirá que escriba uno o dos módulos propios para que funcione como desea. En general, los recomendaría a ambos contra UIL.

Editar (18 de diciembre de 2014): Las cosas han cambiado desde que escribí esta respuesta inicial y sentí que era necesario mejorarla:

Picasso 2.4 es incluso más configurable que las versiones anteriores, y cuando se usa con OkHttp (que es muy recomendable), también puede usar una caché de disco separada para cada instancia, por lo que realmente no hay restricciones en lo que puede hacer. Más importante aún, noté que el rendimiento de Picasso y OkHttp ha mejorado mucho y, en mi opinión, ahora es la solución de carga de imágenes más rápida para Android, punto. Tenga en cuenta que en mi código siempre lo uso .fit()en combinación con .centerCrop()o .centerInside()para reducir el uso de memoria y evitar cambios de tamaño de mapa de bits en el hilo de la interfaz de usuario. Picasso se desarrolla y apoya activamente y eso es ciertamente una gran ventaja.

Volley no ha cambiado mucho, pero noté dos problemas mientras tanto:

  • A veces, con mucha carga, algunas imágenes ya no se cargan debido a daños en la memoria caché del disco.
  • Las miniaturas que se muestran en NetworkImageView (con su tipo de escala establecido en centerCrop) son bastante borrosas en comparación con lo que obtiene con las otras bibliotecas.

Por estas razones decidí dejar de usar Volley.

UIL sigue siendo lento (especialmente la caché de disco) y su API tiende a cambiar con bastante frecuencia.

También probé esta nueva biblioteca llamada Glide 3 que afirma estar más optimizada que Picasso con una API similar a Picasso. Según mi experiencia personal, en realidad es más lento que Picasso y Volley durante las solicitudes de red con mucha carga, incluso cuando se usa en combinación con OkHttp. Peor aún, causó algunos bloqueos con mis aplicaciones en Lollipop al salir de una actividad. Todavía tiene 2 ventajas sobre sus competidores:

  • Admite decodificación de GIF animados
  • Coloca los mapas de bits finales reducidos en la memoria caché del disco, lo que significa que la lectura desde la memoria caché del disco es extremadamente rápida.

Conclusión: ahora recomiendo usar Picasso + OkHttp porque proporciona la mejor flexibilidad, API, rendimiento y estabilidad combinados. Si necesita soporte GIF, también puede considerar Glide.

BladeCoder
fuente
1
Para abordar su último punto en UIL, puede crear tantas ImageLoaderclases y configuraciones diferentes como desee. Solo necesita subclasificar la ImageLoaderclase. Ver aquí: github.com/nostra13/Android-Universal-Image-Loader/issues/…
TalkLittle
Parece un truco, pero gracias por el consejo, es bueno saberlo.
BladeCoder
3
No puedo decir que esté de acuerdo con el sentimiento, usamos Picasso aquí, tengo un álbum con más de 500 imágenes de alta resolución y tenía problemas de rendimiento y memoria, probé UIL y las cosas se resolvieron instantáneamente. Esto fue en una muestra mínima que aisló nuestros problemas que estábamos viendo.
HaMMeReD
Si está mostrando imágenes que tienen una resolución mucho más alta que la pantalla o muchas miniaturas de imágenes de alta resolución, definitivamente debería reducirlas. Creo que UIL hace esto automáticamente y Picasso no lo hace si no especifica las opciones adecuadas, de ahí los problemas de memoria. Personalmente prefiero usar NetworkImageView en Volley, es un widget que reduce la resolución de la imagen cargada a su propio tamaño.
BladeCoder
En UIL, la clase DisplayImageOptions se puede usar si no queremos cambiar o aplicar algún otro procesamiento en una imagen en particular.
Rahul Rastogi
7

Implementé una aplicación que debería obtener y mostrar constantemente imágenes de Internet. Estaba a punto de programar un mecanismo de caché de imágenes, antes de que un amigo me recomendara el cargador de imágenes universal.

El UIL se puede personalizar muy bien. Es tan personalizable que un novato puede hacer algo mal fácilmente. Sin embargo, el UIL fue lento en mi aplicación y se volvió un poco más lento. Mi caso de uso fue un ListView con imágenes.

Ayer buscaba una alternativa a la UIL y descubrí a Picasso. Picasso fue fácil de integrar y usar: solo Picasso.context(context).load(url).into(imageview)y la imagen se pudo integrar más rápido y sin problemas.

Para mí, Picasso es definitivamente la API que debo usar. Mi experiencia con UIL no fue buena.

Samuel L
fuente
Para futuros lectores: Mejor que Picasso es Glide. Echa un vistazo
therealprashant
0

Creo que ImageLoader es más personalizable y flexible en comparación con la biblioteca de Picasso.

Jin Ding
fuente
8
¿Cómo? una pequeña explicación ayudará.
Darpan