Context 와 Uri 를 사용하여, Bitmap 을 가져오는 함수가 deprecated 되어 Replacement 함수로 변경하고 나서 QA 중 에러가 발생했다.
아래와 같이 레거시 방법들을 사용하고 있었고
// (deprecated)
BitmapDrawable(context.resources).bitmap
// (deprecated)
BitmapDrawable(
context.resources,
MediaStore.Images.Media.getBitmap(context.contentResolver, this)
).bitmap
사용했던 문제의 코드
ImageDecoder.decodeBitmap(ImageDecoder.createSource(context.contentResolver, this))
에서 아래와 같은 에러가 발생했다.
java.lang.IllegalStateException: Software rendering doesn't support hardware bitmaps
at android.graphics.BaseCanvas.throwIfHwBitmapInSwMode(BaseCanvas.java:532)
at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:62)
at android.graphics.BaseCanvas.drawBitmap(BaseCanvas.java:120)
at android.graphics.Canvas.drawBitmap(Canvas.java:1434)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529)
....(생략)....
내부 코드를 보니 Bitmap 으로 디코딩 될때,
Build.VERSION_CODES.O 이상이라면, ALLOCATOR_HARDWARE 가 기본 값으로 들어가고 있었다.
Bitmap.Config.HARDWARE is a new Bitmap format that was added in Android O. Hardware Bitmaps store pixel data only in graphics memory and are optimal for cases where the Bitmap is only drawn to the screen.
O 에서 추가된 새로운 비트맵 포맷으로 그래픽 메모리에만 저장되어(불변), 그리는 작업에만 최적화 된다
알고보니 사용하는 라이브러리에서 Bitmap.Config.HARDWARE 에 대한 처리가 되어있지 않았고,
결국은 비트맵 디코딩 방식을 ImageDecoder.ALLOCATOR_SOFTWARE 로 변경했다.
최종적으로 아래와 같은 코드모양이면 WorkAround 한다.
ImageDecode.decodeBitmap 함수를 P 이상 부터 사용할 수 있고, P 이상이라면 O 를 포함하여 모두 SOFTWARE Layer 로 디코딩 되도록 수정했다.
// ImageDecoder.decodeBitmap 함수에서 IOException 던지기 때문에 에러처리가 필요함
@Throws(IOException::class)
fun Uri.uriToBitmap(context: Context): Bitmap =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
ImageDecoder.decodeBitmap(
ImageDecoder.createSource(context.contentResolver, this)
) { decoder: ImageDecoder, _: ImageDecoder.ImageInfo?, _: ImageDecoder.Source? ->
decoder.isMutableRequired = true
decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE
}
} else {
BitmapDrawable(
context.resources,
MediaStore.Images.Media.getBitmap(context.contentResolver, this)
).bitmap
}
참고
http://bumptech.github.io/glide/doc/hardwarebitmaps.html
https://developer.android.com/reference/android/graphics/ImageDecoder#setMutableRequired(boolean)
'Android > Development Tips' 카테고리의 다른 글
Hilt 수박 겉핥기 (0) | 2021.05.07 |
---|---|
DialogFragment 를 상속하는 다이얼로그에서 dismiss 할 때 Tips (0) | 2021.01.10 |
다양한 뷰타입을 가지는 Recyclerview 만들기 (0) | 2020.12.26 |
Clean Architecture (무비 앱) (0) | 2020.04.26 |
KOIN FragmentFactory 사용하기 (3) | 2020.02.29 |