본문 바로가기
Android

Android ANR / Canvas / 메모리 초과 해결방법

by kkong93 2024. 8. 28.
반응형

Canvas를 사용하다보면 ANR이슈가 종종 생기는데 이때 개선할 수 있는 방법이 있다.


1. Bitmap 객체 재사용하기

Bitmap은 메모리 소비가 큰 객체이므로, 반복적인 생성은 메모리 부족 문제를 일으킬 수 있다.

var reusableBitmap: Bitmap? = null

fun getReusableBitmap(width: Int, height: Int): Bitmap {
    if (reusableBitmap == null || reusableBitmap!!.width != width || reusableBitmap!!.height != height) {
        reusableBitmap?.recycle()  // 이전 비트맵을 해제
        reusableBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    }
    return reusableBitmap!!
}

 

 

2. Canvas 클리어링 최소화

Canvas를 그리기전에 항상 클리어하는것은 성능 저하를 유발할 수 있다. 필요한 부분만 덮어쓰도록 하거나, 배경을 효율적으로 설정해야한다.

// 필요할 때만 클리어링
if (shouldClearCanvas) {
    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
}

 

 

3. 그릴때 복잡성 줄이기

불필요한 그리기 작업을 줄이고 가능한 간단하게 유지한다. 필요 없는 텍스트나 그림자를 줄이고, 드로잉 루프에서 반복되는 연산을 피한다.

fun drawSomething(canvas: Canvas) {
    // 복잡한 연산을 그리기 루프 밖으로 옮기기
    val paint = Paint().apply {
        color = Color.RED
        style = Paint.Style.FILL
    }
    canvas.drawRect(0f, 0f, 100f, 100f, paint)
}

 

 

4. View의 invalidate 호출 최적화

invalidate()는 View의 전체 영역을 무효화하여 다시 그리게한다. 빈번한 호출은 성능 저하를 유발할 수 있으므로, 필요할 때만 호출한다.

fun updateView() {
    // 특정 부분만 무효화 (최소 영역을 지정)
    invalidate(left, top, right, bottom)
}

 

 

5. Offsreen Buffer 사용 자제

setLayerType(LAYER_TYPE_SOFTWARE, null) 또는 LAYER_TYPE_HARDWARE 설정은 Offscreen Buffer를 사용하는데, 메모리 사용이 증가할 수 있다. 특별한 이유가 없다면 기본값으로 유지한다. (LAYER_TYPE_NONE)

setLayerType(LAYER_TYPE_NONE, null)

 

 

반응형

댓글