การทำธุรกรรม Binder ล้มเหลวเมื่อวางบิตแมปแบบไดนามิกในวิดเจ็ต


116

ใครช่วยบอกสาเหตุของข้อผิดพลาดในการทำธุรกรรม Binder ที่ล้มเหลวได้ไหม ฉันเห็นข้อความแสดงข้อผิดพลาดนี้ใน logcat ฉันได้รับข้อผิดพลาดนี้ขณะพยายามใส่บิตแมปแบบไดนามิกในวิดเจ็ต ...

คำตอบ:


91

สิ่งนี้เกิดขึ้นเนื่องจากการเปลี่ยนแปลงทั้งหมดใน RemoteViews เป็นแบบอนุกรม (เช่น setInt และ setImageViewBitmap) บิตแมปยังถูกทำให้เป็นอนุกรมในบันเดิลภายใน ขออภัยกลุ่มนี้มีขีด จำกัด ขนาดที่เล็กมาก

คุณสามารถแก้ไขได้โดยการลดขนาดรูปภาพด้วยวิธีนี้:

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

เลือก newHeight ให้เล็กพอ (~ 100 สำหรับทุก ๆ ตารางที่ควรจะอยู่บนหน้าจอ) และใช้สำหรับวิดเจ็ตของคุณแล้วปัญหาของคุณจะได้รับการแก้ไข :)


1
สิ่งที่ฉันไม่ค่อยเข้าใจคือสิ่งที่เกิดขึ้นที่นี่ ฉันใช้ ViewPager กับชุดข้อมูลขนาดใหญ่พอสมควร แต่มันจำทุกอย่างระหว่างเพจได้แม้จะมีสแปมข้อผิดพลาดของ Binder บันเดิลได้รับการเขียนไปยังที่จัดเก็บในตัวเครื่องและจากนั้นกำหนดค่าล่วงหน้าหรืออะไร? ฉันอาจสูญเสียข้อมูลได้หรือไม่หากเพิ่มหน้าเพิ่มเติม
G_V

7
แต่จะทำให้คุณภาพของภาพลดลง
John Joe

64

คุณสามารถบีบอัดบิตแมปเป็นอาร์เรย์ของไบต์จากนั้นคลายการบีบอัดในกิจกรรมอื่นเช่นนี้

บีบอัด !!

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

ยกเลิกการบีบอัด !!

        byte[] bytes = data.getByteArrayExtra("BMP");
        Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

1
สมบูรณ์แบบสิ่งนี้ช่วยลดขนาดบิตแมปได้อย่างมาก
นาวิน

1
ทำไมไม่ใช้ JPEG แทน PNG บีบอัดไม่ดีกว่าเหรอ
mehmet6parmak

3
@ mehmet6parmak PNG ใช้เนื่องจากไม่สูญเสียซึ่งแตกต่างจาก JPEG ใช่ JPEG บีบอัดได้ดีกว่า แต่คุณภาพ (บ้าง) ก็แย่ลง
Petzku

ไม่ได้ผลสำหรับฉัน :( stackoverflow.com/questions/34540819/…
John Joe

รุ่งโรจน์! วิธีแก้ปัญหาที่ยอดเยี่ยมสำหรับการใช้งานชั่วคราวที่ฉันกำลังดำเนินการ แม้ว่าควรหลีกเลี่ยงการส่งผ่านข้อมูลจำนวนมากในขณะที่ใช้ Bundles / Intents
sud007

37

บัฟเฟอร์ธุรกรรม Binder มีขนาดคงที่ จำกัด ปัจจุบันคือ 1Mb ซึ่งใช้ร่วมกันโดยธุรกรรมทั้งหมดที่อยู่ระหว่างดำเนินการสำหรับกระบวนการ ดังนั้นข้อยกเว้นนี้สามารถเกิดขึ้นได้เมื่อมีธุรกรรมจำนวนมากอยู่ระหว่างดำเนินการแม้ว่าธุรกรรมส่วนใหญ่จะมีขนาดปานกลางก็ตาม

อ้างอิงลิงค์นี้


12

ดูคำตอบของฉันในนี้ ด้าย

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

คุณเกินบัฟเฟอร์ธุรกรรม binder โดยการถ่ายโอนองค์ประกอบขนาดใหญ่จากกิจกรรมหนึ่งไปยังกิจกรรมอื่น


ฉันมีปัญหาเดียวกันฉันเพิ่งลบปัญหา putExtra ที่จัดเรียง!
Ivor

8

ฉันได้แก้ไขปัญหานี้โดยการจัดเก็บภาพในที่จัดเก็บข้อมูลภายในแล้วใช้. setImageURI () แทนที่จะเป็น. setBitmap ()


1
และไม่ส่งภาพผ่าน Parcelable จากหน้าจอไปอีกหน้าจอฉันเดาว่าแย่ที่สุดในกรณีนี้
MartinC

3

แนวทางที่ถูกต้องคือใช้setImageViewUri()(ช้าลง) หรือsetImageViewBitmap()และสร้างใหม่RemoteViewทุกครั้งที่คุณอัปเดตการแจ้งเตือน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.