Transaksi binder gagal saat meletakkan bitmap secara dinamis di widget

116

Adakah yang bisa memberi tahu saya alasan kesalahan transaksi pengikat gagal ? Saya dapat melihat pesan kesalahan ini di logcat. Saya mendapatkan kesalahan ini saat mencoba meletakkan bitmap secara dinamis di widget ...

Eby
sumber

Jawaban:

91

Ini disebabkan karena semua perubahan pada RemoteView adalah serial (mis. SetInt dan setImageViewBitmap). Bitmap juga diserialkan menjadi bundel internal. Sayangnya bundel ini memiliki batasan ukuran yang sangat kecil.

Anda dapat mengatasinya dengan memperkecil ukuran gambar dengan cara ini:

 public static Bitmap scaleDownBitmap(Bitmap photo, int newHeight, Context context) {

 final float densityMultiplier = context.getResources().getDisplayMetrics().density;        

 int h= (int) (newHeight*densityMultiplier);
 int w= (int) (h * photo.getWidth()/((double) photo.getHeight()));

 photo=Bitmap.createScaledBitmap(photo, w, h, true);

 return photo;
 }

Pilih newHeight agar cukup kecil (~ 100 untuk setiap persegi yang seharusnya ada di layar) dan gunakan untuk widget Anda, dan masalah Anda akan terpecahkan :)

GalDude33
sumber
1
Apa yang saya tidak begitu mengerti adalah apa yang sebenarnya terjadi di sini. Saya menggunakan ViewPager dengan kumpulan data yang cukup besar, namun ia mengingat semua yang ada di antara halaman meskipun ada spam kesalahan binder. Apakah paket ditulis ke penyimpanan lokal dan kemudian diambil sebelumnya atau apa? Dapatkah saya kehilangan data jika saya menambahkan lebih banyak halaman?
G_V
7
Tetapi ini akan mengurangi kualitas gambar
John Joe
64

Anda dapat mengompresi bitmap sebagai larik byte dan kemudian mengekstraknya di aktivitas lain, seperti ini.

Kompres!!

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] bytes = stream.toByteArray(); 
        setresult.putExtra("BMP",bytes);

Buka kompres !!

        byte[] bytes = data.getByteArrayExtra("BMP");
        Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Nicolás Loaiza
sumber
1
Sempurna, ini mengurangi ukuran bitmap secara signifikan.
Navin
1
mengapa tidak menggunakan JPEG daripada PNG? Bukankah lebih baik dikompresi?
mehmet6parmak
3
@ mehmet6parmak PNG digunakan karena bersifat lossless, tidak seperti JPEG. Ya, JPEG kompres lebih baik, tetapi kualitas (agak) menderita sebagai hasilnya.
Petzku
tidak bekerja untuk saya :( stackoverflow.com/questions/34540819/…
John Joe
Pujian! Solusi hebat untuk implementasi sementara yang sedang saya kerjakan. Meskipun mengirimkan data yang berat harus dihindari saat menggunakan Bundles / Intents.
sud007
37

Buffer transaksi Binder memiliki ukuran tetap terbatas, saat ini 1Mb, yang digunakan bersama oleh semua transaksi yang sedang berlangsung untuk proses tersebut. Konsekuensinya, pengecualian ini dapat dilakukan ketika ada banyak transaksi yang sedang berlangsung bahkan ketika sebagian besar transaksi individual berukuran sedang.

lihat tautan ini

dharam
sumber
12

Lihat jawaban saya di utas ini .

intent.putExtra("Some string",very_large_obj_for_binder_buffer);

Anda melebihi buffer transaksi pengikat dengan mentransfer elemen besar dari satu aktivitas ke aktivitas lain.

Balaji Dubey
sumber
Saya memiliki masalah yang sama saya hanya menghapus masalah putExtra diurutkan!
Ivor
8

Saya telah memecahkan masalah ini dengan menyimpan gambar di penyimpanan internal dan kemudian menggunakan .setImageURI () daripada .setBitmap ().

MartinC
sumber
1
dan tidak melewatkan gambar melalui Parcelable dari layar ke layar atau lebih, saya rasa itu yang terburuk dalam kasus ini
MartinC
3

Pendekatan yang tepat adalah menggunakan setImageViewUri()(lebih lambat) atau setImageViewBitmap()dan membuat ulang RemoteViewsetiap kali Anda memperbarui notifikasi.

Alexander Woodblock
sumber