En mi funcion:
public void getPointMarkerFromUrl(final String url, final OnBitmapDescriptorRetrievedListener listener) {
final int maxSize = context.getResources().getDimensionPixelSize(R.dimen.icon_max_size);
Target t = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
if (bitmap != null)
listener.bitmapRetrieved(getBitmapDescriptorInCache(url, bitmap));
else
loadDefaultMarker(listener);
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
loadDefaultMarker(listener);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(context)
.load(url)
.resize(maxSize, maxSize)
.into(t);
}
OnBitmapLoaded () nunca se llama la primera vez que cargo imágenes. He leído algún tema como https://github.com/square/picasso/issues/39 que recomienda usar el método fetch (Target t) (parece ser un problema de referencia débil ...), pero esta función no está disponible en la última versión de picasso (2.3.2). Solo tengo un método fetch (), pero no puedo usar into (mytarget) al mismo tiempo
¿Podría explicarme cómo usar fetch () con un Target personalizado, por favor? Gracias.
Doc: http://square.github.io/picasso/javadoc/com/squareup/picasso/RequestCreator.html#fetch--
Respuestas:
Como lo señalaron los otros encuestados (@lukas y @mradzinski), Picasso solo mantiene una referencia débil al
Target
objeto. Si bien puede almacenar una referencia fuerteTarget
en una de sus clases, esto puede ser problemático si lasTarget
referenciasView
de alguna manera, ya que efectivamente también mantendrá una referencia fuerte a esoView
(que es una de las cosas que Picasso explícitamente te ayuda a evitar).Si se encuentra en esta situación, le recomiendo etiquetar
Target
aView
:Este enfoque tiene la ventaja de permitir que Picasso se encargue de todo por usted. Administrará los
WeakReference
objetos para cada una de sus vistas: tan pronto como ya no sea necesario, cualquierTarget
proceso que procese la imagen también se liberará, por lo que no estará atascado con pérdidas de memoria debido a objetivos de larga duración, pero su objetivo durará mientras su vista esté viva.fuente
Picasso no tiene una referencia fuerte al objeto Target, por lo tanto, se está recolectando basura y
onBitmapLoaded
no se llama.La solución es bastante simple, solo haga una fuerte referencia al
Target
.fuente
View
implementoTarget
.Object.equals(Object)
yObject.hashCode()
métodos. ¿Tienes una muestra de trabajo?Si tuviera ImageView, simplemente haría así: imageView.setTag (target);
Uso la siguiente solución para cargar mapas de bits en las notificaciones, por lo que solo necesito un mapa de bits.
Por lo tanto, crear Set bruja almacenará objetos Target y los eliminará al finalizar la carga.
fuente
fuente
Aquí está la solución para aquellos que no están usando una vista. Este método auxiliar utiliza una lista para almacenar temporalmente el objeto de destino hasta que se devuelva un resultado para que no se gc'd:
fuente
Como dijo @lukas (y citando), Picasso no tiene una fuerte referencia al objeto Target. Para evitar la recolección de basura, debe tener una fuerte referencia al objeto.
Sobre el método fetch (). Está bastante claro en la documentación que fetch () no se debe usar con un ImageView ni un Target, es solo para "calentar" el caché y nada más, por lo que no podrá usarlo de la manera que usted querer.
Te recomiendo que tengas una referencia fuerte como explicó @lukas, debería funcionar. De lo contrario, abra un nuevo problema en la página de GitHub del proyecto.
fuente
Encontré un problema similar y mantener la referencia al objetivo no ayudó en absoluto, así que utilicé el siguiente código que devuelve un mapa de bits:
en el lado negativo -> no hay devolución de llamada y no puede llamar a esta función en el hilo principal, debe ejecutar esta función en un hilo de fondo como en el siguiente ejemplo:
¡Otra cosa que funciona mucho mejor es usar Glide!
Necesitaba usar ambos, ya que el propósito de mi proyecto era usar 2 API de descarga de imágenes diferentes para mostrar una galería de imágenes y darle al usuario la capacidad de elegir qué API usar.
Tengo que decir que me sorprendieron los resultados, la API de Glide funcionó a la perfección en todos los aspectos (el objetivo de Glide no tiene una referencia débil) mientras Picasso me dio un infierno (esa fue la primera vez que usé Glide, por lo general usé Picasso hasta ahora, Parece que hoy va a cambiar ^^).
fuente
Me enfrenté al mismo problema, pero cuando cambio la dependencia como se menciona a continuación, ahora funciona correctamente.
fuente