$ cat ./notes/2026-09-04-0835.mdrss ↗

메모 · 2026-09-04 08:35

Android Drawable.mutate() — 공유 상태 오염 막기

같은 리소스 ID로 가져온 Drawable은 서로 다른 인스턴스처럼 보여도 내부 ConstantState(색상·모양 등)를 공유한다. setColor(), setStroke()처럼 상태를 바꾸는 메서드를 그냥 호출하면 그 변경이 같은 리소스를 쓰는 다른 뷰에도 그대로 번진다 — 화면 A 버튼 색을 바꿨는데 화면 B 버튼도 같이 바뀌는, 원인 추적이 까다로운 버그가 됨.

mutate()는 공유 상태에서 분리해 독립된 복사본을 만든다. 이후 변경은 이 인스턴스에만 영향.

<shape> XML 하나를 버튼·입력 필드 등 여러 화면에서 재사용하면서 런타임에 테마 색으로 칠하는 코드라면 getDrawable() 직후 mutate()를 항상 붙이는 게 안전. 실제로 뒤져보니 이런 패턴으로 140번 호출돼 있었음 — 리소스 하나가 4곳에서 재사용되는 경우도 흔함.

2026-09-04 08:35