| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 | 31 |
- Android WebView
- Android
- 습관만들기
- 영어공부
- 알고리즘 자바
- android recyclerview
- Android 12
- 코틀린 코루틴
- Kotlin
- scope function
- Android Interceptor
- Kotlin FCM
- coroutine
- OkHttp Interceptor
- 안드로이드 카카오 로그인
- Android ViewPager2
- WebView
- Android ProgressBar
- Android 12 대응
- DataBinding
- 안드로이드 갤러리 접근
- 66챌린지
- 프로그래머스 알고리즘
- 카카오 알고리즘
- Android Jetpack
- Android Navigation
- 영어독립365
- 안드로이드
- MVP Architecture
- Java
- Today
- Total
목록분류 전체보기 (145)
주맨의 개발노트
브랜치를 바꾸려면 하던 일을 먼저 치워야 합니다. git stash로 밀어두고, 브랜치를 옮기고, 일을 끝내고, 다시 돌아와서 꺼냅니다. 익숙한 순서입니다.그런데 Android 프로젝트에서는 이 왕복이 생각보다 비쌉니다. 브랜치를 옮기면 소스가 통째로 바뀌므로 Gradle sync가 다시 돌고, 증분 빌드 상태가 무효화되면서 다음 빌드에서 상당 부분을 다시 컴파일합니다. 세 줄 고치면 끝나는 핫픽스 앞뒤로 그보다 긴 시간이 붙습니다.git worktree는 이 왕복 자체를 없애는 기능입니다. 브랜치를 바꾸는 대신 작업 디렉토리를 하나 더 두는 방식입니다. 다만 공짜는 아니고, Android에서는 치러야 할 것이 몇 가지 있습니다. 이 글에서는 worktree가 정확히 무엇을 격리하고 무엇을 격리하지 않는..
Compose를 배우면 상태 호이스팅(state hoisting)을 "왜 해야 하느냐"는 질문에 대해 대개 같은 답을 듣습니다. 재사용성이 좋아지고, 테스트가 쉬워지고, 관심사가 분리되고, 단방향 데이터 흐름(UDF)을 따르고, 단일 진실 공급원(SSOT)을 보장한다는 것입니다.전부 맞는 말이고, 상태 호이스팅을 하는 이유도 결국 여기에 있습니다. 요구사항이 바뀌어도 고쳐야 할 코드가 적고, 한 번 만든 컴포넌트를 여러 화면에서 다시 쓰고, UI를 손보는 일과 상태 로직을 손보는 일이 서로 발목 잡지 않는 — 그런 코드를 만들기 위해서입니다.다만 이 답은 "무엇이 좋아지는가"까지만 말해 줍니다. 그 효과가 어떤 원리로 생기는지, 그리고 이 원칙을 어디까지 적용해야 하는지는 한 걸음 더 들어가야 보입니다...
Compose로 화면을 설계하다 보면 한 번쯤 마주치는 고민이 있습니다. 화면 하나를 만들 때 Composable 함수를 어떻게 쪼갤 것인가 하는 문제입니다.보통 두 가지 선택지를 두고 고민하게 됩니다. 하나는 *Screen() 내부에서 *Content()를 호출하고, *Content()가 UI 렌더링을 담당하는 구조입니다. 다른 하나는 *Screen() 내부에서 곧바로 여러 Component 함수들을 조합해서 UI 렌더링까지 책임지는 구조입니다. 후자는 결국 *Content()의 역할을 *Screen()이 그대로 떠안는 셈입니다.두 경우 모두 전제는 같습니다. 개별 UI 조각(Component)은 이미 따로 분리되어 있다고 가정합니다. 그러니 여기서 다루고 싶은 것은 “Component를 어떻게 나눌 ..
Claude Code를 프로젝트에 적극적으로 활용하면서 개발 속도는 확실히 빨라졌습니다. 새 화면의 기본 구조를 만들고, 반복적인 보일러플레이트를 작성하고, 유사한 패턴을 이어가는 작업에서 특히 효과가 컸습니다.그런데 속도가 빨라진 만큼 새로운 문제가 생겼습니다. 코드 리뷰에서 MVI 패턴 위반이 발견되기 시작했습니다. CLAUDE.md에 MVI 규칙을 상세히 적어뒀는데도, Agent가 생성한 코드가 실제로 그것을 따랐는지 보장할 수 없었습니다.이 글은 그 문제를 해결하기 위해 마틴 파울러의 Harness Engineering 개념을 참고하고, Detekt 커스텀 룰을 Sensor로 도입한 경험을 정리한 기록입니다.Agent가 MVI 규칙을 어겼다제 프로젝트의 feature 모듈은 MVI 패턴을 표준으로..
사내 테스트 앱을 확인하는 과정은 생각보다 자주 개발 흐름을 끊습니다. PR이 develop에 병합됐다는 알림을 받고 실제 앱에서 확인하려면, 하던 작업을 잠시 멈추고 브랜치를 바꾸고 빌드한 뒤 앱을 설치해야 합니다.한 번이면 괜찮습니다. 하지만 하루에 여러 PR이 병합되고, 그때마다 변경사항을 확인해야 하는 상황이 반복되면 이야기가 달라집니다. 빌드 시간보다 더 크게 느껴졌던 것은 작업하던 맥락을 내려놓고 확인 모드로 전환해야 하는 비용이었습니다.그래서 develop 브랜치에 Firebase App Distribution 배포 파이프라인을 붙였습니다. 목표는 단순했습니다. PR이 병합되면 테스트 앱이 자동으로 배포되고, 팀원은 새 빌드를 받아 바로 확인할 수 있는 흐름을 만드는 것이었습니다.수동 확인 ..
Compose로 화면을 만들다 보면 Recomposition이라는 말을 자주 듣게 됩니다. 상태가 바뀌면 Composable이 다시 실행되고, Compose는 변경된 상태를 기준으로 UI를 최신 상태로 맞춥니다.처음에는 이 정도로 이해해도 개발하는 데 큰 문제는 없습니다. 하지만 화면이 복잡해지고 리스트가 커지고 상태가 여러 계층으로 전달되기 시작하면, 단순히 "상태가 바뀌면 다시 그린다"는 설명만으로는 부족해집니다.특히 UiState를 잘게 나누고, data class에 val만 사용했는데도 특정 Composable이 계속 다시 실행되는 경우가 있습니다. 이때 문제의 원인이 되는 개념이 바로 Compose의 Stability입니다.이런 코드 쓴 적 있지 않나요?Compose 화면에서 ViewModel이..
프로젝트에는 이미 CI가 갖춰져 있었습니다. PR이 develop 브랜치에 병합되면 빌드와 테스트가 자동으로 실행되는 환경이었습니다.다음 단계는 CD였습니다. Firebase App Distribution으로 앱 빌드를 자동 배포하는 파이프라인을 준비하면서, 자연스럽게 릴리즈 노트를 어떻게 만들 것인지가 문제로 올라왔습니다.배포 자체는 자동화하는데, 매번 릴리즈 노트만 사람이 손으로 정리해야 한다면 자동화 흐름이 어색해집니다. 특히 저희 프로젝트는 PR 라벨을 이미 비교적 일관되게 붙이고 있었기 때문에, 이 라벨을 기준으로 변경사항을 자동 분류할 수 있지 않을까 생각했습니다.그 과정에서 GitHub Actions 마켓플레이스의 오픈소스 액션인 release-drafter/release-drafter를 적..
들어가며Claude Code를 프로젝트에 적극적으로 활용하다 보면, 빠르게 코드를 만들어주는 만큼 팀 컨벤션을 놓치는 장면도 자주 보게 됩니다. 저희 팀에서는 특히 디자인 시스템 컴포넌트를 사용해야 하는 화면에서 Claude가 Material3 기본 컴포넌트를 선택하는 문제가 반복됐습니다.이 글은 CLAUDE.md로 규칙을 알려주는 것에서 한 단계 더 나아가, PostToolUse 훅으로 디자인 시스템 위반을 자동 감지한 경험을 정리한 기록입니다. 핵심은 Claude에게 더 길게 설명하는 것이 아니라, 반드시 지켜야 하는 규칙을 코드로 검사하는 구조를 함께 두는 것입니다.Claude가 Material3 AppBar를 사용했다새 화면을 만들 때 Claude에게 맡기면 Screen, Scaffold, Vie..