일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- xcode13
- 닷넷
- Cloudflare
- aws lambda
- hot reload
- AWS
- SecureStorage
- Xamarin Forms
- 지도
- 구글지도
- Android
- 구글맵
- 흑우마스터
- 망할
- v
- c#
- iOS노치
- Xamarin
- ASP.NET Web API
- 비주얼스튜디오2022
- ABLY
- vpc
- 자마린
- .net maui
- n8n
- 프로그래밍
- 배포
- 개발
- MAUI
- 안드로이드
- Today
- Total
흑우마스터의 마법의 공간
.NET MAUI 안드로이드 CarouselView 내 Bitmap 재활용 오류의 원인과 해결 방법 본문
.NET MAUI로 앱을 개발하면서 안드로이드 환경에서 CarouselView 내 이미지 컨트롤을 넣고 페이지를 전환하다 보면 다음과 같은 오류가 발생할 수 있다
Java.Lang.RuntimeException: 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap@f8c1cee'
이 오류는 안드로이드의 Bitmap 객체가 이미 recycle() 메서드를 통해 메모리에서 해제된 이후, 다시 재사용을 시도할 때 발생한다. 특히 CarouselView처럼 이미지가 빠르게 전환되는 경우에 자주 나타나는 문제이다.
.NET MAUI 안드로이드에서는 내부적으로 Glide 또는 유사한 이미지 로딩 라이브러리를 사용하는데, 이들은 로드된 Bitmap을 내부에서 관리하고 재활용(BitmapPool)에 반환하는 구조를 가지고 있다.
이 과정에서 개발자가 Bitmap을 다른 작업에 참조하거나, CarouselView에 반복적으로 그리는 작업을 수행할 경우 충돌이 발생할 가능성이 있다.
.NET MAUI 커뮤니티에서는 이 문제를 해결하기 위해 별도의 핸들러(Handler)를 하라고 해서 해보긴 했다.
#if ANDROID
using Microsoft.Maui.Handlers;
#endif
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
// 기존 코드...
#if ANDROID
ImageHandler.Mapper.PrependToMapping(nameof(Microsoft.Maui.IImage.Source), (handler, view) =>
{
handler.PlatformView?.Clear();
});
#endif
return builder.Build();
}
}
하지만 실제 테스트 결과, 이 방법은 별다른 효과가 없었고, FFImageLoadingImage와 같은 라이브러리를 사용하면 문제가 해결되긴 했으나 이는 근본적인 해결책이라고 보기 어려웠다.
가장 빠르고 확실한 해결 방법은 이미지 컨트롤에 반드시 WidthRequest와 HeightRequest 값을 명시적으로 설정함으로 해결했다. 비트맵이 정확한 크기를 미리 계산하고 할당할 수 있도록 하여 재활용 과정에서 발생하는 오류를 효과적으로 방지하는거라 생각되는데 맞는지는 잘 모르겠다.
다만, 동적인 화면 구성이나 이미지 비율을 유지해야 하는 경우에는 크기를 고정하는 것이 좀 번거로울 수도 있기 때문에 비율에 따라 재계산하는 추가 작업이 필요하다.
MauiReactor 같은 MVU 방식에서는 Render() 또는 Invalidate()를 호출하면 SkiaSharp처럼 Surface가 다시 그려지기 때문에 문제가 덜하지만, 일반 .NET MAUI 환경에서는 추가적인 고민이 필요할 것이다.
추가적으로, 만약 이미지 처리 작업이 더 필요하다면 Bitmap의 복사본을 만들어가면서 교체하는 식도 가능할거 같긴한데 이건 커스텀으로 만들어야 되지만 Glide의 메모리 관리 방식과 독립적으로 안정적인 Bitmap 사용이 가능하니까 꼭 해야 되는 사람이 있다면 커스텀 컨트롤로 만드는 것도 방법이지만 대부분 사이즈를 직접 줄 것 같다.