$ tail -f blog.mdrss ↗

Win-Dev Log

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

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

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

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

AI 티 안나는 아이콘 창고 SVG 아이콘 13만개를 모아둔 사이트. 모두 무료에 상업적 사용 가능, 출처 표기 필요 X https://koboyo.com/icons

Android - SRC_IN은 드로어블의 불투명 픽셀을 소스 색으로 그대로 대체해서 텍스트와 동일한 색으로 보이게 만든다.

UI 이름 몰라도 바이브 코딩용 프롬프트 찾는 법(NameThatUI)

‘버튼을 누르면 화면 오른쪽 아래 잠깐 떴다가 사라지는 저장 완료 메시지’ -> 이런 식으로 검색하면 그에 맞는 검색 결과 UI 및 프롬프트까지 제공해주는 사이트

https://namethatui.com/?ref=blog.secondbrush.co.kr

안드로이드 가로/세로 판별 기준 + UI 전환 시점 정리

판별 기준

  • Configuration.orientation (ORIENTATION_LANDSCAPE/PORTRAIT) 이 제일 안전한 기준. 기기의 natural orientation과 현재 rotation을 시스템이 이미 합쳐서 계산해준 값이라 직접 조합할 필요가 없음.
  • Display.getRotation() (ROTATION_0/90/180/270) 단독으로는 판단하면 안 됨 — natural orientation이 landscape인 태블릿류는 rotation 0이 곧 landscape라, 폰 기준으로 짠 로직을 그대로 쓰면 뒤집힘.
  • width/height 직접 비교도 가능하지만, 폴더블·멀티윈도우 화면에서는 orientation보다 WindowSizeClass(compact/medium/expanded)로 판단하는 쪽이 요즘 권장 방식. 가로모드라도 접힌 폴더블처럼 실제 가용 폭이 좁을 수 있어서 orientation 하나로는 레이아웃 분기가 안 맞음.

UI 변경 시점

  • layout-land/ 리소스 분기를 쓰면 Activity가 재생성되면서 자동으로 바뀜 — 타이밍을 따로 신경 쓸 필요는 없지만 상태 저장(onSaveInstanceState/ViewModel)은 필수.
  • configChanges="orientation|screenSize"로 재생성을 막았다면 onConfigurationChanged() 콜백 시점에 반영. 이 콜백은 회전 애니메이션이 끝나고 새 Configuration이 확정된 뒤에 불리므로, 애니메이션 도중에 미리 바꾸면 깜빡임만 생김.
  • Compose는 LocalConfiguration.current가 그 확정 시점에 recomposition을 트리거해서 별도 처리 없이 자연스럽게 맞음.
  • 멀티윈도우/분할화면 리사이즈는 orientation 변화 없이 screenSize만 바뀌는 경우가 있어서, configChanges에 screenSize도 같이 선언해야 그 시점을 놓치지 않음.

Claude Code - /security-review

  • 코드 근처에서 위 명령어 입력하면 커밋 전에 SQL 인젝션, XSS, 인증 허점을 검사해준다.
  • AI로 작업하면서 절대적으로 사람이 주의해야 할 부분 중 하나가 보안입니다.