Transazione binder non riuscita durante l'inserimento dinamico di una bitmap in un widget


116

Qualcuno può dirmi il motivo dell'errore di transazione del raccoglitore non riuscita ? Riesco a vedere questo messaggio di errore in logcat. Ricevo questo errore mentre provo a inserire dinamicamente una bitmap in un widget ...

Risposte:


91

Ciò è dovuto al fatto che tutte le modifiche a RemoteViews vengono serializzate (ad esempio setInt e setImageViewBitmap). Le bitmap vengono inoltre serializzate in un bundle interno. Sfortunatamente questo pacchetto ha un limite di dimensioni molto ridotto.

Puoi risolverlo ridimensionando le dimensioni dell'immagine in questo modo:

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

Scegli newHeight per essere abbastanza piccolo (~ 100 per ogni quadrato che dovrebbe occupare sullo schermo) e usalo per il tuo widget e il tuo problema sarà risolto :)


1
Quello che non capisco è cosa succede esattamente qui. Sto usando un ViewPager con un set di dati abbastanza grande, ma ricorda tutto tra le pagine nonostante lo spam di errore del raccoglitore. Il pacchetto viene scritto nella memoria locale e quindi precaricato o cosa? Posso perdere dati se aggiungo più pagine?
G_V

7
Ma questo ridurrà la qualità dell'immagine
John Joe

64

Puoi comprimere la bitmap come un array di byte e quindi decomprimerla in un'altra attività, come questa.

Comprimere!!

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

Uncompress !!

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

1
Perfetto, questo riduce notevolmente la dimensione della bitmap.
Navin

1
perché non usare JPEG invece di PNG? non è meglio compresso?
mehmet6parmak

3
@ mehmet6parmak PNG viene utilizzato perché è senza perdita di dati, a differenza di JPEG. Sì, JPEG si comprime meglio, ma la qualità (un po ') ne risente.
Petzku


Complimenti! Ottima soluzione alternativa per un'implementazione temporanea su cui stavo lavorando. Sebbene il passaggio di dati pesanti dovrebbe essere evitato durante l'utilizzo di bundle / intenti.
sud007

37

Il buffer delle transazioni di Binder ha una dimensione fissa limitata, attualmente 1Mb, che è condivisa da tutte le transazioni in corso per il processo. Di conseguenza, questa eccezione può essere generata quando sono in corso molte transazioni anche quando la maggior parte delle singole transazioni sono di dimensioni moderate.

fare riferimento a questo collegamento


12

Vedi la mia risposta in questo thread.

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

Stai superando il buffer di transazione del binder trasferendo uno o più elementi di grandi dimensioni da un'attività a un'altra.


Ho avuto lo stesso problema Ho appena rimosso il problema putExtra risolto!
Ivor

8

Ho risolto questo problema memorizzando le immagini nella memoria interna e quindi utilizzando .setImageURI () anziché .setBitmap ().


1
e non passare le immagini attraverso Parcelable da uno schermo all'altro o giù di lì, immagino che sia la cosa peggiore in questo caso
MartinC,

3

L'approccio giusto consiste nell'usare setImageViewUri()(più lentamente) o setImageViewBitmap()e ricreare RemoteViewi messaggi di posta elettronica ogni volta che si aggiorna la notifica.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.