Dalam fungsi saya:
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 () tidak pernah disebut pertama kali saya memuat gambar. Saya telah membaca beberapa topik seperti https://github.com/square/picasso/issues/39 yang merekomendasikan untuk menggunakan metode fetch (Target t) (sepertinya merupakan masalah referensi lemah ...), tetapi fungsi ini tidak tersedia dalam rilis terakhir picasso (2.3.2). Saya hanya memiliki metode fetch (), tetapi saya tidak dapat menggunakan (mytarget) pada saat yang sama
Bisakah Anda menjelaskan kepada saya bagaimana cara menggunakan fetch () dengan Target kustom? Terima kasih.
Doc: http://square.github.io/picasso/javadoc/com/squareup/picasso/RequestCreator.html#fetch--
Jawaban:
Seperti dicatat oleh responden lain (@lukas dan @mradzinski), Picasso hanya menyimpan referensi yang lemah ke
Target
objek. Meskipun Anda dapat menyimpan referensi yang kuatTarget
di salah satu kelas Anda, ini masih bisa menjadi masalah jikaTarget
referensi tersebut denganView
cara apa pun, karena Anda juga akan secara efektif menyimpan referensi yang kuat untuk ituView
juga (yang merupakan salah satu hal yang Picasso secara eksplisit membantu Anda menghindari).Jika Anda berada dalam situasi ini, saya sarankan memberi tag
Target
keView
:Pendekatan ini bermanfaat membiarkan Picasso menangani semuanya untuk Anda. Ini akan mengelola
WeakReference
objek untuk setiap tampilan Anda - segera setelah satu tidak diperlukan lagi,Target
pemrosesan apa pun gambar juga akan dirilis, sehingga Anda tidak terjebak dengan kebocoran memori karena target jangka panjang, tetapi Target Anda akan bertahan selama pandangannya hidup.sumber
Picasso tidak memiliki referensi yang kuat ke objek Target, sehingga menjadi sampah yang dikumpulkan dan
onBitmapLoaded
tidak dipanggil.Solusinya cukup sederhana, cukup buat referensi kuat ke
Target
.sumber
View
menerapkanTarget
.Object.equals(Object)
danObject.hashCode()
metode. apakah Anda memiliki sampel yang berfungsi?Jika saya memiliki ImageView, saya akan membuatnya seperti ini: imageView.setTag (target);
Saya menggunakan solusi berikutnya untuk memuat Bitmap ke notifikasi, jadi saya hanya perlu bitmap.
Jadi buat Set witch akan menyimpan objek Target dan menghapusnya saat selesai memuat.
sumber
sumber
Berikut adalah solusi untuk mereka yang tidak menggunakan tampilan. Metode helper ini menggunakan daftar untuk menyimpan sementara objek target hingga hasilnya dikembalikan sehingga tidak gc'd:
sumber
Seperti kata @ lukas (dan mengutip), Picasso tidak memiliki referensi yang kuat ke objek Target. Untuk menghindari pengumpulan sampah, Anda harus memiliki referensi kuat ke objek.
Tentang metode fetch (). Cukup jelas dalam dokumentasi bahwa fetch () tidak dapat digunakan dengan ImageView atau Target, hanya untuk "menghangatkan" cache dan tidak ada yang lain, jadi Anda tidak akan dapat menggunakannya dengan cara yang Anda inginkan. ingin.
Saya sarankan Anda memegang referensi kuat seperti @ lukas menjelaskan, itu harus bekerja. Jika tidak, silakan buka masalah baru di halaman GitHub proyek.
sumber
Saya mengalami masalah serupa dan menahan referensi ke target tidak membantu sama sekali jadi saya menggunakan kode berikut yang mengembalikan Bitmap:
di sisi bawah -> tidak ada panggilan balik dan Anda tidak dapat memanggil fungsi ini di utas utama, Anda harus menjalankan fungsi ini pada utas latar belakang seperti pada contoh berikut:
Hal lain yang jauh lebih baik adalah menggunakan Glide!
Saya perlu menggunakan keduanya karena tujuan dari proyek saya adalah menggunakan 2 api unduhan gambar yang berbeda untuk menampilkan galeri gambar dan memberi pengguna kemampuan untuk memilih api mana yang akan digunakan.
Saya harus mengatakan, saya kagum dengan hasilnya, api Glide bekerja dengan sempurna di setiap aspek (target Glide tidak memiliki referensi yang lemah) ketika Picasso memberi saya neraka (itu adalah pertama kalinya saya menggunakan Glide, saya biasanya menggunakan Picasso sejauh ini, sepertinya hari ini akan berubah ^^).
sumber
Saya telah menghadapi masalah yang sama tetapi ketika saya mengubah ketergantungan seperti yang disebutkan di bawah, Ini berfungsi dengan baik sekarang.
sumber