Column + verticalScroll() vs LazyColumn, 무엇이 더 성능이 좋을까?

Jetpack Compose에서 스크롤 가능한 리스트 UI를 구현할 때 Column + verticalScroll()과 LazyColumn 중 무엇을 선택해야 하는지 고민하는 경우가 많다. 결론부터 말하면, 리스트라면 대부분 LazyColumn이 더 적합하다. 1. Column + verticalScroll()의 동작 방식 Column에 verticalScroll()을 붙이면 전체 내용을 한 번에 모두 그린다. 즉, 아이템이 5~10개 정도로 매우 적다면 큰 차이는 없다. 하지만 20개 이상부터는 체감 차이가 … Read more

sealed class vs enum, 언제 무엇을 써야 할까?

Kotlin에서 상태나 결과를 표현할 때 enum과 sealed class 사이에서 고민하는 경우가 많다.두 타입은 겉보기엔 비슷해 보이지만, 의도와 쓰임새는 분명히 다르다.핵심은 “값의 집합인가, 타입의 집합인가”다. enum: 고정된 값의 집합 enum은 값이 미리 정해진 유한한 목록일 때 가장 적합하다. 특징 예시 이런 경우 ExampleStatus는 when 문에서도 모든 케이스가 명확하게 드러난다. sealed class: 서로 다른 타입의 묶음 sealed … Read more

스레드와 Allocator, 그리고 왜 같이 이야기해야 하는가

이미지 처리, 추론 파이프라인, 고성능 시스템을 다루다 보면자연스럽게 “스레드”와 “allocator”라는 단어를 만나게 된다.이 둘은 각각 따로 보면 단순하지만, 같이 쓰이기 시작하는 순간 매우 중요한 설계 포인트가 된다. 이 글에서는 스레드(Thread)란 무엇인가 정의 스레드는 프로그램 안에서 실제로 코드를 실행하는 실행 흐름 단위다. 중요한 점은 서로 다른 스레드가 같은 코드, 같은 데이터에 동시에 접근할 수 있다는 사실이다. … Read more

Jetpack Compose에서 Lottie 재생 제어하기

animateLottieCompositionAsState vs LottieAnimatable 차이와 선택 기준 Jetpack Compose에서 Lottie 애니메이션을 붙일 때 자주 쓰는 방식은 두 가지다. 둘 다 같은 라이브러리(Lottie Compose) 안에 있지만, 재생 제어 모델이 완전히 다르다.특히 “토글로 잠깐 보여주는 애니메이션”이나 “항상 0프레임부터 다시 재생” 같은 요구가 있으면 선택이 갈린다. 1) animateLottieCompositionAsState: 선언형, 자동 재생 핵심 개념 animateLottieCompositionAsState는 Compose의 상태 변화에 맞춰 진행(progress)을 … Read more

왜 Android / Kotlin에서는 RAII가 불가능한가

C++의 RAII는 자원 관리 문제를 매우 강력하게 해결한다.그렇다면 자연스럽게 이런 질문이 생긴다. “왜 Kotlin이나 Android에서는 RAII를 쓰지 않는가?” 정확히 말하면,Android / Kotlin에서는 RAII를 언어 차원에서 구현할 수 없다. RAII의 전제 조건 RAII가 성립하려면 다음 조건이 필요하다. C++은 이 세 가지를 모두 만족한다. Kotlin / Java의 객체 생명주기 Kotlin과 Java는 GC 기반 언어다. 다음 코드를 보자. … Read more

Android에서 API 키 안전하게 관리하기 – Secrets Gradle Plugin 사용법

프로젝트하다가 실수로 API 키를 GitHub에 푸시한 적 있으신가요? 저는 있습니다… Google Maps API 키를 하드코딩해놨다가 커밋하고 나서 식은땀이 났던 기억이 나네요. 오늘은 Google에서 제공하는 Secrets Gradle Plugin으로 API 키를 안전하게 관리하는 방법을 공유해볼게요. 기존에 어떻게 했나? 보통 이런 식으로 했죠: // ❌ 절대 하면 안 되는 방법 class MapsActivity : AppCompatActivity() { private val API_KEY … Read more

안드로이드 클린 아키텍처 정리

안드로이드 클린 아키텍처 정리 안드로이드 클린 아키텍처 정리 클린 아키텍처란? 최근에 클린 아키텍처를 안드로이드 프로젝트에 적용해보고 있는데, 처음에는 계층이 왜 이렇게 복잡한지 이해가 안 됐다. 하지만 막상 구조를 나눠서 코드를 작성해보니 “UI와 로직, 데이터가 뒤엉키지 않는다”는 게 이렇게 큰 장점일 줄은 몰랐다. 기본적으로 계층은 세 가지로 나뉜다: presentation: UI, ViewModel domain: UseCase, Entity, Repository Interface … Read more

Jetpack Compose에서 TTS 간단하게 구현하기 – rememberTextToSpeech 커스텀 훅 만들기

최근에 어르신들을 위한 앱을 만들면서 음성 안내 기능을 넣어야 했어요. Compose로 작업하다 보니 TTS도 Compose스럽게 쓰고 싶더라구요. 그래서 간단한 커스텀 Composable을 만들어봤습니다. 왜 Compose에서 TTS가 까다로울까? TTS는 Android의 전통적인 API라서 Compose의 선언적 패러다임과 잘 안 맞아요. 특히 이런 부분들이 신경 쓰였습니다: 초기화가 비동기로 진행됨 Activity 생명주기에 맞춰 정리해야 함 Recomposition 때마다 새로 생성되면 안 됨 … Read more

Firebase Remote Config로 데모 앱 유효기간 관리하기 – 빌드 시간 기반 자동 만료 시스템

최근에 회사에서 SDK 데모 앱을 만들면서 겪은 일입니다. 무제한으로 사용하게 둘 수는 없고… 그렇다고 매번 만료일을 하드코딩해서 빌드하기도 번거롭더라구요. 그래서 Firebase Remote Config를 활용해서 꽤 괜찮은 해결책을 만들었습니다. 오늘은 그 과정을 공유해보려고 합니다. 문제 상황 저희가 원했던 건 이런 거였어요: 빌드할 때마다 자동으로 3일 사용 기한 설정 “며칠만 더 써보고 싶다”고 하면 즉시 연장 가능 … Read more

Windows에서 Fastlane + Firebase로 앱 배포 자동화하기

iOS/Android 앱 배포 자동화를 위한 Fastlane을 Windows에서 설정하는 방법을 정리해보았습니다. Mac이 아닌 Windows 환경에서도 충분히 Fastlane을 활용할 수 있습니다! 📋 사전 준비사항 Fastlane을 설치하기 전에 다음 프로그램들이 필요합니다: Ruby: Fastlane은 Ruby 기반으로 동작합니다 Git Bash: Unix 명령어를 Windows에서 사용하기 위해 필요합니다 Android Studio 또는 IntelliJ IDEA: 개발 환경 🔧 Step 1: Ruby 설치하기 Windows에서 Ruby를 … Read more