Dans ma fonction:
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 () n'est jamais appelé la première fois que je charge des images. J'ai lu des rubriques comme https://github.com/square/picasso/issues/39 qui recommandent 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
Pouvez-vous m'expliquer comment utiliser fetch () avec une cible personnalisée s'il vous plaît? Je vous remercie.
Doc: http://square.github.io/picasso/javadoc/com/squareup/picasso/RequestCreator.html#fetch--
Réponses:
Comme le notent les autres répondants (@lukas et @mradzinski), Picasso ne garde qu'une faible référence à l'
Target
objet. Bien que vous puissiez stocker une référence forteTarget
dans l'une de vos classes, cela peut toujours être problématique si lesTarget
références sont d'uneView
manière ou d'une autre, car vous conserverez également une référence forte à celaView
(ce qui est l'une des choses que Picasso vous aide explicitement à éviter).Si vous êtes dans cette situation, je vous recommande de marquer le
Target
surView
:Cette approche a l'avantage de laisser Picasso s'occuper de tout pour vous. Il gérera les
WeakReference
objets pour chacune de vos vues - dès que vous n'enTarget
aurez plus besoin, quel que soit le traitement, l'image sera également libérée, vous n'êtes donc pas coincé avec des fuites de mémoire dues à des cibles de longue durée, mais votre cible durera tant que sa vue est vivante.la source
Picasso ne contient pas de référence forte à l'objet Target, il est donc en cours de récupération de place et
onBitmapLoaded
n'est pas appelé.La solution est assez simple, il suffit de faire une forte référence au
Target
.la source
View
outilTarget
.Object.equals(Object)
etObject.hashCode()
méthodes. avez-vous un échantillon de travail?Si j'avais ImageView, je ferais simplement comme ceci: imageView.setTag (cible);
J'utilise la solution suivante pour charger des bitmaps dans les notifications, donc je n'ai besoin que de bitmap.
Alors créez Set witch stockera les objets Target et les supprimera à la fin du chargement.
la source
la source
Voici la solution pour ceux qui n'utilisent pas de vue. Cette méthode d'assistance utilise une liste pour stocker temporairement l'objet cible jusqu'à ce qu'un résultat soit renvoyé afin qu'il ne soit pas gc'd:
la source
Comme @lukas l'a dit (et citant), Picasso ne contient pas de référence forte à l'objet Target. Pour éviter le garbage collection, vous devez contenir une référence forte à l'objet.
À propos de la méthode fetch (). Il est assez clair dans la documentation que fetch () ne doit pas être utilisé avec une ImageView ni une cible, c'est juste pour "réchauffer" le cache et rien d'autre, donc vous ne pourrez pas l'utiliser comme vous vouloir.
Je vous recommande de tenir une référence forte comme @lukas l'a expliqué, cela devrait fonctionner. Sinon, veuillez ouvrir un nouveau problème sur la page GitHub du projet.
la source
J'ai rencontré un problème similaire et la détention de référence à la cible n'a pas du tout aidé, j'ai donc utilisé le code suivant qui renvoie un Bitmap:
en revanche -> 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:
Une autre chose qui fonctionne beaucoup mieux est simplement d'utiliser Glide!
J'avais besoin de les utiliser tous les deux car le but de mon projet était d'utiliser 2 API de téléchargement d'images différentes pour afficher une galerie d'images et pour donner à l'utilisateur la possibilité de choisir l'API à utiliser.
Je dois dire que j'ai été étonné par les résultats, l'api de Glide fonctionnait parfaitement dans tous les aspects (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, j'utilisais habituellement Picasso jusqu'à présent, on dirait qu'aujourd'hui ça va changer ^^).
la source
J'avais rencontré le même problème, mais lorsque je change la dépendance comme mentionné ci-dessous, cela fonctionne correctement maintenant.
la source