In meiner Funktion:
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 () wird beim ersten Laden von Bildern nie aufgerufen. Ich habe ein Thema wie https://github.com/square/picasso/issues/39 gelesen, das die Verwendung der Fetch-Methode (Target t) empfiehlt (es scheint ein Problem mit schwachen Referenzen zu sein ...), aber diese Funktion ist in der letzten Version von picasso (2.3.2) nicht verfügbar. Ich habe nur eine fetch () -Methode, kann sie aber nicht gleichzeitig in (mytarget) verwenden
Können Sie mir bitte erklären, wie man fetch () mit einem benutzerdefinierten Ziel verwendet? Danke dir.
Doc: http://square.github.io/picasso/javadoc/com/squareup/picasso/RequestCreator.html#fetch--
Antworten:
Wie von den anderen Befragten (@lukas und @mradzinski) festgestellt, behält Picasso nur einen schwachen Bezug zum
Target
Objekt. Während Sie eine starke ReferenzTarget
in einer Ihrer Klassen speichern können , kann dies dennoch problematisch sein, wenn dieTarget
ReferenzenView
in irgendeiner Weise a sind, da Sie effektiv auch eine starke Referenz darauf behaltenView
(was eines der Dinge ist, die Picasso ist hilft Ihnen ausdrücklich zu vermeiden).Wenn Sie sich in dieser Situation befinden, würde ich empfehlen, das
Target
mit dem Tag zu versehenView
:Dieser Ansatz hat den Vorteil, dass Picasso alles für Sie erledigt. Es verwaltet die
WeakReference
Objekte für jede Ihrer Ansichten - sobald eines nicht mehr benötigt wird, wird unabhängig von derTarget
Verarbeitung des Bildes auch die Freigabe des Bilds freigegeben, sodass Sie nicht aufgrund langlebiger Ziele an Speicherlecks hängen bleiben, sondern Ihr Ziel bleibt erhalten solange seine Sicht lebt.quelle
Picasso enthält keinen starken Verweis auf das Zielobjekt, daher wird der Müll gesammelt und
onBitmapLoaded
nicht aufgerufen.Die Lösung ist ganz einfach, verweisen Sie einfach stark auf die
Target
.quelle
View
GerätTarget
.Object.equals(Object)
undObject.hashCode()
Methoden. Hast du eine Arbeitsprobe?Wenn ich ImageView hätte, würde ich einfach so machen: imageView.setTag (Ziel);
Ich verwende die nächste Lösung zum Laden von Bitmaps in Benachrichtigungen, daher benötige ich nur Bitmap.
Erstellen Sie also Set, in dem Zielobjekte gespeichert und nach dem Laden entfernt werden.
quelle
quelle
Hier ist die Lösung für diejenigen, die keine Ansicht verwenden. Diese Hilfsmethode verwendet eine Liste, um das Zielobjekt vorübergehend zu speichern, bis ein Ergebnis zurückgegeben wird, damit es nicht gc'd wird:
quelle
Wie @lukas sagte (und zitierte), enthält Picasso keinen starken Verweis auf das Zielobjekt. Um eine Speicherbereinigung zu vermeiden, müssen Sie einen starken Verweis auf das Objekt enthalten.
Informationen zur Methode fetch (). In der Dokumentation ist ziemlich klar, dass fetch () weder mit einer ImageView noch mit einem Target verwendet werden darf, sondern nur, um den Cache "aufzuwärmen" und sonst nichts, sodass Sie ihn nicht so verwenden können, wie Sie es möchten wollen.
Ich empfehle Ihnen, eine starke Referenz zu haben, wie @lukas erklärt hat, es sollte funktionieren. Wenn nicht, öffnen Sie bitte eine neue Ausgabe auf der GitHub-Seite des Projekts.
quelle
Ich bin auf ein ähnliches Problem gestoßen, und das Verweisen auf das Ziel hat überhaupt nicht geholfen. Daher habe ich den folgenden Code verwendet, der eine Bitmap zurückgibt:
auf der anderen Seite -> es gibt keinen Rückruf und Sie können diese Funktion nicht im Hauptthread aufrufen. Sie müssen diese Funktion in einem Hintergrundthread wie im folgenden Beispiel ausführen:
Eine andere Sache, die viel besser funktioniert, ist die Verwendung von Glide!
Ich musste beide verwenden, da der Zweck meines Projekts darin bestand, zwei verschiedene Bild-Download-APIs zu verwenden, um eine Bildergalerie anzuzeigen und dem Benutzer die Möglichkeit zu geben, die zu verwendende API auszuwählen.
Ich muss sagen, ich war erstaunt über die Ergebnisse, Glides API hat in jeder Hinsicht einwandfrei funktioniert (Glides Ziel hat keinen schwachen Bezug), während Picasso mir die Hölle gab (das war mein erstes Mal mit Glide, ich habe bisher normalerweise Picasso verwendet). scheint sich heute zu ändern ^^).
quelle
Ich hatte das gleiche Problem, aber wenn ich die Abhängigkeit wie unten erwähnt ändere, funktioniert sie jetzt ordnungsgemäß.
quelle