Nieudana transakcja segregatora podczas dynamicznego umieszczania mapy bitowej w widgecie

116

Czy ktoś może mi podać przyczynę nieudanej transakcji bindera? Widzę ten komunikat o błędzie w logcat. Otrzymuję ten błąd podczas próby dynamicznego umieszczenia mapy bitowej w widżecie ...

Eby
źródło

Odpowiedzi:

91

Jest to spowodowane tym, że wszystkie zmiany w RemoteViews są serializowane (np. SetInt i setImageViewBitmap). Mapy bitowe są również serializowane do pakietu wewnętrznego. Niestety ten pakiet ma bardzo mały limit rozmiaru.

Możesz rozwiązać ten problem, zmniejszając rozmiar obrazu w ten sposób:

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

Wybierz newHeight, aby był wystarczająco mały (~ 100 na każdy kwadrat, jaki powinien zająć na ekranie) i użyj go jako widgetu, a problem zostanie rozwiązany :)

GalDude33
źródło
1
Nie do końca rozumiem, co dokładnie się tutaj dzieje. Używam ViewPagera z dość dużym zestawem danych, ale zapamiętuje wszystko między stronami pomimo spamu z błędami segregatora. Czy pakiet jest zapisywany w lokalnej pamięci, a następnie wstępnie pobierany, czy co? Czy mogę stracić dane, jeśli dodam więcej stron?
G_V,
7
Ale to obniży jakość obrazu
John Joe
64

Możesz skompresować bitmapę jako tablicę bajtów, a następnie zdekompresować ją w innym działaniu, takim jak to.

Kompresja!!

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

Rozpakuj !!

        byte[] bytes = data.getByteArrayExtra("BMP");
        Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Nicolás Loaiza
źródło
1
Idealnie, to znacznie zmniejsza rozmiar mapy bitowej.
Navin
1
dlaczego nie użyć JPEG zamiast PNG? czy nie jest lepiej skompresowany?
mehmet6parmak
3
@ mehmet6parmak PNG jest używany, ponieważ jest bezstratny, w przeciwieństwie do JPEG. Tak, JPEG kompresuje się lepiej, ale w rezultacie jakość (nieco) ucierpi.
Petzku
nie działa dla mnie :( stackoverflow.com/questions/34540819/…
John Joe
Sława! Świetne obejście tymczasowej implementacji, nad którą pracowałem. Chociaż podczas korzystania z pakietów / intencji należy unikać przekazywania ciężkich danych.
sud007
37

Bufor transakcji Binder ma ograniczony stały rozmiar, obecnie 1 MB, który jest współdzielony przez wszystkie transakcje w toku procesu. W konsekwencji ten wyjątek może zostać zgłoszony, gdy istnieje wiele transakcji w toku, nawet jeśli większość pojedynczych transakcji ma umiarkowany rozmiar.

skieruj ten link

dharam
źródło
12

Zobacz moją odpowiedź w tym wątku.

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

Przekraczasz bufor transakcji segregatora, przenosząc duże elementy z jednego działania do drugiego.

Balaji Dubey
źródło
Miałem ten sam problem, który po prostu usunąłem putExtra problem rozwiązany!
Ivor
8

Rozwiązałem ten problem, przechowując obrazy w pamięci wewnętrznej, a następnie używając .setImageURI () zamiast .setBitmap ().

MartinC
źródło
1
i nie przesyłaj obrazów przez Parcelable z ekranu na ekran, myślę, że to jest najgorsze w tym przypadku
MartinC
3

Właściwym podejściem jest użycie setImageViewUri()(wolniej) lub setImageViewBitmap()i ponowne utworzenie RemoteViews za każdym razem, gdy aktualizujesz powiadomienie.

Alexander Woodblock
źródło