onBitmapLoaded d’object cible non appelé lors du premier chargement

Dans ma fonction:

public void getPointMarkerFromUrl(final Ssortingng url, final OnBitmapDescriptorResortingevedListener 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.bitmapResortingeved(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 () ne s’appelle jamais la première fois que je charge des images. J’ai lu un sujet comme https://github.com/square/picasso/issues/39 qui recommande d’utiliser la méthode fetch (Target t) (cela semble être un problème de référence faible …), mais cette fonction n’est pas disponible dans la dernière version de picasso (2.3.2). Je n’ai qu’une méthode fetch (), mais je ne peux pas utiliser dans (mytarget) en même temps

Pourriez-vous m’expliquer comment utiliser fetch () avec une cible personnalisée? Je vous remercie.

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

Comme l’ont noté les autres répondants (@lukas et @mradzinski), Picasso ne garde qu’une faible référence à l’object Target . Bien que vous puissiez stocker une Target référence forte dans l’une de vos classes, cela peut toujours poser problème si la Target référence une View de quelque manière que ce soit, car vous garderez également une référence forte à cette View (qui est l’une des les choses que Picasso vous aide explicitement à éviter).

Si vous êtes dans cette situation, je vous recommande de marquer la Target sur la View :

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

Cette approche a l’avantage de permettre à Picasso de tout gérer pour vous. Il gérera les objects WeakReference pour chacune de vos vues – dès que vous n’en aurez plus besoin, quel que soit le traitement de l’image par la Target , vous ne rencontrerez pas de memory leaks dues à des cibles de longue durée, mais à votre cible. durera aussi longtemps que sa vue est vivante.

Picasso ne contient pas de référence forte à l’object Target, il est donc récupéré et onBitmapLoaded n’est pas appelé.

La solution est simple, faites référence à la cible.

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

Si j’avais ImageView, je ferais simplement comme ceci: imageView.setTag (target);

J’utilise la solution suivante pour charger les bitmaps dans les notifications, donc je n’ai besoin que de bitmap.

Donc, créez un object qui stockera les objects cibles et les supprimera lors du chargement final.

 final Set 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() { } }); 

Comme l’a dit @lukas (et en citant), Picasso ne fait pas référence à l’object Target. Pour éviter la récupération de place, vous devez avoir une référence forte à l’object.

À propos de la méthode fetch () Il est assez clair dans la documentation que fetch () ne doit pas être utilisé avec ImageView ni avec une cible, il s’agit simplement de “réchauffer” le cache et rien d’autre, de sorte que vous ne pourrez pas l’utiliser comme vous le feriez. vouloir.

Je vous recommande de tenir une référence forte comme @lukas expliqué, ça devrait marcher. Sinon, ouvrez un nouveau numéro sur la page GitHub du projet.

J’ai rencontré un problème similaire et la référence à la cible n’a pas aidé du tout, j’ai donc utilisé le code suivant qui renvoie une image bitmap:


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

du côté inférieur -> il n’y a pas de rappel et vous ne pouvez pas appeler cette fonction sur le thread principal, vous devez exécuter cette fonction sur un thread d’arrière-plan comme dans l’exemple suivant:


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

Une autre chose qui fonctionne beaucoup mieux est d’utiliser Glide!

J’avais besoin de les utiliser tous les deux puisque le but de mon projet était d’utiliser 2 API de téléchargement d’images différentes pour montrer une galerie d’images et donner à l’utilisateur la possibilité de choisir quelle api utiliser.

Je dois avouer que j’ai été étonné par les résultats, que l’api de Glide a parfaitement fonctionné (la cible de Glide n’a pas de référence faible), alors que Picasso m’a donné l’enfer (c’était la première fois que j’utilisais Glide. On dirait qu’aujourd’hui ça va changer ^^).

Voici la solution pour ceux qui n’utilisent pas de vue. Cette méthode d’assistance utilise une liste pour stocker temporairement l’object cible jusqu’à ce qu’un résultat soit renvoyé afin qu’il ne soit pas gc:

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