nueijeel
[Android] OutOfMemoryError 본문
glide 라이브러리를 사용해 이미지를 출력하는 작업 중 아래와 같은 오류가 발생했다.
java.lang.OutOfMemoryError: Failed to allocate a 83070912 byte allocation with 6291456 free bytes and 12MB until OOM, max allowed footprint 396321520, growth limit 402653184
찾아보니 이미지 뷰가 담을 수 있는 이미지 용량을 넘어서 할당 오류가 발생한 것이다.
해결 시도
1. glide의 override 속성 지정
Glide.with(mainActivity).load(productImageList[position])
.into(holder.carouselImageViewRowProductImage)
위의 원래 코드에서
Glide.with(mainActivity).load(productImageList[position])
.override(200, 200)
.into(holder.carouselImageViewRowProductImage)
override 속성 지정을 통해 이미지 크기를 축소해서 표시한다.
실행해보니 여전히 같은 오류가 발생했다.
2. AndroidManifest.xml에 largeHeap 속성 추가
안드로이드 프로젝트 용량이 커서 largeHeap을 사용하게 해주는 코드이다.
이것도 마찬가지로 오류가 났다.
3, Glide에 load할 이미지 형식 Bitmap으로 변경
albumLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
//이미지 가져오기 성공
if(it.resultCode == RESULT_OK){
//사진 여러장 선택한 경우
if(it.data?.clipData != null){
val count = it.data?.clipData?.itemCount
for(idx in 0 until count!!){
val imageUri = it.data?.clipData?.getItemAt(idx)?.uri
productImageList.add(imageUri!!)
}
}
//한장 선택한 경우
else{
it.data?.data?.let { uri ->
val imageUri = it.data?.data
if(imageUri != null){
productImageList.add(imageUri)
}
}
}
//recycler view 갱신
fragmentRegisterProductBinding.recyclerViewRegisterProductImage.adapter?.notifyDataSetChanged()
}
}
원래는 이 코드를 통해 이미지 Uri를 담은 리스트를 생성하고, 해당 리스트의 항목을 load 했었는데 bitmap 방식이 메모리가 덜 차지된다고 해서
uri 그대로 집어넣지 않고 bitmap으로 decode해서 load 해줬다.
//사진 여러장 선택한 경우
if(it.data?.clipData != null){
val count = it.data?.clipData?.itemCount
//SDK 버전 P 이상
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
for(idx in 0 until count!!){
val imageUri = it.data?.clipData?.getItemAt(idx)?.uri
val bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(mainActivity.contentResolver, imageUri!!))
productImageList.add(bitmap)
}
}
//P 미만
else{
for(idx in 0 until count!!){
val imageUri = it.data?.clipData?.getItemAt(idx)?.uri
val bitmap = MediaStore.Images.Media.getBitmap(mainActivity.contentResolver, imageUri)
productImageList.add(bitmap)
}
}
}
그런데도 안됨 ㅜㅜ
4. bitmapfactory.options().insamplesize 지정
albumLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
val option = BitmapFactory.Options()
option.inSampleSize = 4
//이미지 가져오기 성공
if(it.resultCode == RESULT_OK){
//사진 여러장 선택한 경우
if(it.data?.clipData != null){
val count = it.data?.clipData?.itemCount
for(idx in 0 until count!!){
val imageUri = it.data?.clipData?.getItemAt(idx)?.uri
val inputStream = mainActivity.contentResolver.openInputStream(imageUri!!)
val bitmap = BitmapFactory.decodeStream(inputStream, null, option)
inputStream?.close()
productImageList.add(bitmap!!)
}
}
BitmapFactory의 Options에 inSampleSize를 지정해 비트맵을 decode 하면 크기를 축소한 비트맵을 구할 수 있다고 해서 적용해보니까 오류가 해결됐다!!
이미지 출력은 코드만 작성하면 뷰에 알아서 뜨니까
이미지 용량까지는 생각해본 적이 없는데,, 오늘 부로 그 부분도 신경써야겠다는 걸 알게됐다!
참고 자료
https://kkangsnote.tistory.com/156
728x90
'Android > 에러 및 문제 해결' 카테고리의 다른 글
[Android] 앱 삭제 후 이전 데이터가 남아있는 문제 (0) | 2024.03.11 |
---|---|
[Android] 카카오 로그인 구현하기 - 카카오계정 로그인이 안되는 현상 (0) | 2024.02.16 |
[Android] NoModelLoaderAvailableException 오류 (0) | 2023.08.22 |
[Android] CompilationErrorException 오류 (0) | 2023.08.22 |
Android 앱에서 google map api 설정 (0) | 2023.07.23 |