onBitmapLoaded del objeto de destino no llamado en la primera carga
En mi función:
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 un 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 usarlo into(mytarget) al mismo tiempo
¿Podría explicarme cómo utilizar fetch() con un objetivo personalizado, por favor? Gracias.
Documento: http://square.github.io/picasso/javadoc/com/squareup/picasso/RequestCreator.html#fetch--
Como señalaron los demás encuestados (@lukas y @mradzinski), Picasso sólo mantiene una débil referencia al Target
objeto. Si bien puedes almacenar una referencia fuerte Target
en una de tus clases, esto aún puede ser problemático si las Target
referencias son View
de alguna manera, ya que efectivamente también mantendrás una referencia fuerte a esa View
(que es una de las cosas que Picasso te ayuda explícitamente a evitar).
Si se encuentra en esta situación, le recomiendo etiquetar Target
a View
:
final ImageView imageView = ... // The view Picasso is loading an image into
final Target target = new Target{...};
imageView.setTag(target);
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, cualquier Target
procesamiento de la imagen también se liberará, por lo que no tendrá pérdidas de memoria debido a objetivos de larga duración, pero su objetivo durará. mientras su vista esté viva.
Si tuviera ImageView, simplemente lo haría así: imageView.setTag(target);
Utilizo la siguiente solución para cargar mapas de bits en las notificaciones, por lo que solo necesito mapas de bits.
Entonces, cree un conjunto que almacenará los objetos de destino y los eliminará al finalizar la carga.
final Set<Target> protectedFromGarbageCollectorTargets = new HashSet<>();
private void loadBitmap(String url) {
Target bitmapTarget = new BitmapTarget();
protectedFromGarbageCollectorTargets.add(bitmapTarget);
Picasso.with(context).load(url).into(bitmapTarget);
}
class BitmapTarget implements Target {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
//handle bitmap
protectedFromGarbageCollectorTargets.remove(this);
}
}
}
@Override
public void onBitmapFailed(Drawable drawable) {
protectedFromGarbageCollectorTargets.remove(this);
}
@Override
public void onPrepareLoad(Drawable drawable) {
}
}
ImageView profile = new ImageView(context);
Picasso.with(context).load(URL).into(profile, new Callback() {
@Override
public void onSuccess() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {//You will get your bitmap here
Bitmap innerBitmap = ((BitmapDrawable) profile.getDrawable()).getBitmap();
}
}, 100);
}
@Override
public void onError() {
}
});