ウィジェットにビットマップを動的に配置するときに失敗したバインダートランザクション


116

誰かが失敗したバインダートランザクションエラーの理由を教えてもらえますか?このエラーメッセージはlogcatで確認できます。ウィジェットにビットマップを動的に配置しようとすると、このエラーが発生します...

回答:


91

これは、RemoteViewへのすべての変更がシリアル化されているために発生します(たとえば、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を使用していますが、バインダーエラースパムにもかかわらず、ページ間のすべてを記憶しています。バンドルはローカルストレージに書き込まれてからプリフェッチされますか?さらにページを追加すると、データが失われる可能性がありますか?
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
完璧、これはビットマップのサイズを大幅に減らします。
Navin、2014

1
なぜPNGではなくJPEGを使用しないのですか?より圧縮されていませんか?
mehmet6parmak

3
@ mehmet6parmak PNGは、JPEGとは異なり、ロスレスであるため使用されます。はい、JPEGの方が圧縮率は高くなりますが、結果として品質が(ある程度)低下します。
Petzku


賞賛!私が取り組んでいた一時的な実装の素晴らしい回避策。バンドル/インテントの使用中は、大量のデータを渡すことは避けてください。
sud007 2017

37

バインダーのトランザクションバッファーには、現在1Mbの制限された固定サイズがあり、プロセスで進行中のすべてのトランザクションによって共有されます。その結果、個々のトランザクションの大部分が中程度のサイズであっても、進行中のトランザクションが多い場合、この例外がスローされる可能性があります。

このリンクを参照


12

この スレッドで私の答えを見てください。

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

1つのアクティビティから別のアクティビティに大きな要素を転送することにより、バインダートランザクションバッファーを超えています。


同じ問題があり、ソートされたputExtra問題を削除しました!
2016年

8

画像を内部ストレージに保存し、.setBitmap()ではなく.setImageURI()を使用してこの問題を解決しました。


1
画面から画面などにParcelableを介して画像を渡さないでください。この場合、これは最悪だと思います
MartinC

3

正しい方法は、setImageViewUri()(遅い)またはを使用し、通知を更新するたびにsetImageViewBitmap()を再作成RemoteViewすることです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.