Falha na transação do fichário ao colocar um bitmap dinamicamente em um widget

116

Alguém pode me dizer o motivo do erro de transação do fichário com falha? Posso ver essa mensagem de erro no logcat. Estou recebendo este erro ao tentar colocar um bitmap dinamicamente em um widget ...

Eby
fonte

Respostas:

91

Isso ocorre porque todas as alterações em RemoteViews são serializadas (por exemplo, setInt e setImageViewBitmap). Os bitmaps também são serializados em um pacote interno. Infelizmente, este pacote tem um limite de tamanho muito pequeno.

Você pode resolvê-lo reduzindo o tamanho da imagem desta forma:

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

Escolha newHeight para ser pequeno o suficiente (~ 100 para cada quadrado que ele deve ocupar na tela) e use-o para seu widget, e seu problema será resolvido :)

GalDude33
fonte
1
O que não entendo muito bem é o que acontece aqui exatamente. Estou usando um ViewPager com um conjunto de dados bastante grande, mas ele se lembra de tudo entre as páginas, apesar do spam de erro do fichário. O pacote é gravado no armazenamento local e, em seguida, pré-buscado ou o quê? Posso perder dados se adicionar mais páginas?
G_V
7
Mas isso reduzirá a qualidade da imagem
John Joe
64

Você pode compactar o bitmap como uma matriz de bytes e descompactá-lo em outra atividade, como esta.

Comprimir!!

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

Descompacte !!

        byte[] bytes = data.getByteArrayExtra("BMP");
        Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Nicolás Loaiza
fonte
1
Perfeito, isso reduz significativamente o tamanho do bitmap.
Navin
1
por que não usar JPEG em vez de PNG? não é melhor compactado?
mehmet6parmak
3
@ mehmet6parmak PNG é usado porque não tem perdas, ao contrário do JPEG. Sim, JPEG é melhor compactado, mas a qualidade (um pouco) é prejudicada.
Petzku
não funciona para mim :( stackoverflow.com/questions/34540819/…
John Joe
Kudos! Excelente solução alternativa para uma implementação temporária em que estava trabalhando. Embora a transmissão de dados pesados ​​deva ser evitada ao usar Bundles / Intents.
sud007
37

O buffer de transação do Binder tem um tamanho fixo limitado, atualmente 1 MB, que é compartilhado por todas as transações em andamento para o processo. Consequentemente, essa exceção pode ser lançada quando há muitas transações em andamento, mesmo quando a maioria das transações individuais é de tamanho moderado.

consulte este link

dharam
fonte
12

Veja minha resposta neste tópico.

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

Você está excedendo o buffer de transação do fichário ao transferir grandes elementos de uma atividade para outra.

Balaji Dubey
fonte
Eu tive o mesmo problema, acabei de remover o problema putExtra resolvido!
Ivor
8

Resolvi esse problema armazenando imagens no armazenamento interno e usando .setImageURI () em vez de .setBitmap ().

MartinC
fonte
1
e não passe as imagens por Parcelable de tela para tela ou então, acho que é o pior neste caso
MartinC
3

A abordagem certa é usar setImageViewUri()(mais lento) ou setImageViewBitmap()e recriar RemoteViews toda vez que você atualizar a notificação.

Alexander Woodblock
fonte