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 ...

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 :)


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

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


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


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.


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 ().


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.