위젯에 동적으로 비트 맵을 넣을 때 바인더 트랜잭션 실패


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
그러나 이것은 이미지 품질 줄일
존 조

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 2015-04-06

3
@ mehmet6parmak PNG는 JPEG와 달리 무손실이기 때문에 사용됩니다. 예, JPEG는 더 잘 압축되지만 결과적으로 품질 (다소)이 저하됩니다.
Petzku

:( 나를 위해 작동하지 않습니다 stackoverflow.com/questions/34540819/...
존 조에게

명성! 내가 작업하고 있던 임시 구현에 대한 훌륭한 해결 방법입니다. 번들 / 인 텐트를 사용하는 동안 무거운 데이터를 전달하는 것은 피해야합니다.
sud007 jul.

37

바인더 트랜잭션 버퍼는 현재 1Mb의 제한된 고정 크기를 가지며 프로세스를 위해 진행중인 모든 트랜잭션에서 공유됩니다. 따라서 대부분의 개별 트랜잭션이 중간 크기 인 경우에도 진행중인 트랜잭션이 많으면이 예외가 throw 될 수 있습니다.

링크를 참조하십시오


12

스레드 에서 내 대답을 참조하십시오 .

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

한 활동에서 다른 활동으로 큰 요소를 전송하여 바인더 트랜잭션 버퍼를 초과하고 있습니다.


같은 문제가 있었지만 putExtra 문제가 정렬되었습니다!
Ivor

8

내부 저장소에 이미지를 저장 한 다음 .setBitmap () 대신 .setImageURI ()를 사용하여이 문제를 해결했습니다.


1
그리고 Parcelable을 통해 화면에서 화면으로 이미지를 전달하지 마십시오.이 경우 최악 인 것 같습니다
MartinC

3

올바른 접근 방식은 알림을 업데이트 할 때마다 를 사용 setImageViewUri()(느리게)하거나 setImageViewBitmap()를 다시 RemoteView만드는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.