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


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.