pinturas paloma pablo obras nombre hijos guernica faciles cubismo completo biografia picasso

picasso - paloma - onBitmapLoaded del objeto Target no invocado en la primera carga



picasso obras (7)

Aquí está la solución para aquellos que no están usando una vista. Este método de ayuda utiliza una lista para almacenar temporalmente el objeto de destino hasta que se devuelve un resultado para que no se gc''d:

private List<Target> targets = new ArrayList<>(); public void downloadBitmap(final Context context, final String url, final MyCallback callback) { Target target = new Target() { @Override public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) { targets.clear(); callback.onSuccess(bitmap); } @Override public void onBitmapFailed(Drawable errorDrawable) { targets.clear(); callback.onFailure(null); } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } }; targets.add(target); Picasso.with(context).load(url).into(target); }

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); }

El 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 utilizar el método fetch (Target t) (parece ser un problema de referencia débil ...), pero esta función no está disponible en el último lanzamiento de picasso (2.3.2). Solo tengo un método fetch (), pero no puedo usarlo (mytarget) al mismo tiempo

¿Podría explicarme cómo usar fetch () con un objetivo personalizado, por favor? Gracias.

Doc: http://square.github.io/picasso/javadoc/com/squareup/picasso/RequestCreator.html#fetch--


Como dijo @lukas (y citando), Picasso no hace una referencia fuerte al objeto Target. Para evitar la recolección de basura, debe contener una fuerte referencia al objeto.

Acerca del método fetch () Está bastante claro en la documentación que fetch () no se debe usar con un ImageView ni un Target, solo para "calentar" el caché y nada más, por lo que no podrá usarlo de la forma que querer.

Te recomiendo que tengas una referencia fuerte, como @lukas explicó, debería funcionar. De lo contrario, abra un nuevo problema en la página de GitHub del proyecto.


Como señalaron los otros encuestados (@lukas y @mradzinski), Picasso solo mantiene una referencia débil al objeto Target . Si bien puede almacenar un Target referencia fuerte en una de sus clases, esto aún puede ser problemático si el Target referencia a una View de alguna manera, ya que de hecho también mantendrá una fuerte referencia a esa View (que es una de las cosas que Picasso explícitamente te ayuda a evitar).

Si te encuentras en esta situación, te recomendaría etiquetar el Target a la View :

final ImageView imageView = ... // The view Picasso is loading an image into final Target target = new Target{...}; imageView.setTag(target);

Este enfoque tiene el beneficio de dejar que Picasso lo maneje todo por ti. WeakReference objetos WeakReference para cada una de sus vistas, tan pronto como ya no se necesite, cualquier procesamiento de Target que la imagen también se lanzará, para que no se quede atascado con pérdidas de memoria debido a objetivos de larga duración, pero su objetivo durará mientras su vista esté viva.


Me encontré con un problema similar y mantener la referencia al objetivo no me ayudó para nada, así que usé el siguiente código que devuelve un mapa de bits:

Bitmap bitmap = picasso.with(appContext).load(url).get();

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:

handlerThread = new HandlerThread(HANDLER_THREAD_NAME); handlerThread.start(); Handler handler = new Handler(handlerThread.getLooper()); handler.post(new Runnable() { @Override public void run() { Bitmap bitmap = null; try { bitmap = picasso.with(appContext).load(url).get(); } catch (IOException e) { e.printStackTrace(); }finally { if (bitmap != null) { //do whatever you wanna do with the picture. //for me it was using my own cache imageCaching.cacheImage(imageId, bitmap); } } } });

Otra cosa que funciona mucho mejor es simplemente usar Glide!

Necesitaba usar ambos, ya que el objetivo de mi proyecto era utilizar 2 api de descarga de imágenes diferentes para mostrar una galería de imágenes y dar al usuario la posibilidad de elegir qué API usar.

Debo 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) cuando Picasso me dio un infierno (esa fue la primera vez que uso Glide, usé Picasso hasta ahora, parece que hoy va a cambiar ^^).


Picasso no contiene una referencia fuerte al objeto Target, por lo tanto, se está recogiendo basura y no se llama a BitmapLoaded.

La solución es muy simple, solo haz una fuerte referencia al objetivo.

public class MyClass { private Target mTarget = new Target() {...}; public void getPointMarkerFromUrl(final String url, final OnBitmapDescriptorRetrievedListener listener) { Picasso.with(context) .load(url) .resize(maxSize, maxSize) .into(mTarget); } }


Si tuviera ImageView lo haría de esta manera: imageView.setTag (target);

Utilizo la siguiente solución para cargar Bitmaps en notificaciones, por lo que solo necesito un mapa de bits.

Así que crea Set witch que almacenará los objetos Target y los eliminará al finalizar la carga.

final Set<Target> protectedFromGarbageCollectorTargets = new HashSet<>(); private void loadBitmap(String url) { Target bitmapTarget = new BitmapTarget(nEvent); 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() { } });