Chrome 확장 프로그램 다국어 지원: Manifest V3에서 5개 언어 적용하기

이미지
Chrome 확장 프로그램 다국어 지원: Manifest V3에서 5개 언어 적용하기 Chrome 확장 프로그램을 영어로만 만들다가 한국어, 일본어, 스페인어, 독일어까지 지원하려면 단순히 문자열을 번역하는 것만으로는 부족합니다. Manifest V3의 chrome.i18n 구조, 정적 HTML과 JavaScript에서 생성되는 동적 UI, 컨텍스트 메뉴, 기존 사용자 데이터까지 함께 살펴야 합니다. 최근 Simple Side Note 1.4.0에 5개 언어를 적용하면서 사용한 구조를 기준으로, 기존 확장 프로그램을 안전하게 다국어화하는 방법을 정리합니다. 1. _locales 디렉터리 만들기 Chrome 확장 프로그램의 기본 번역 단위는 _locales/<언어>/messages.json 입니다. text _locales/ en/messages.json ko/messages.json ja/messages.json es/messages.json de/messages.json 각 파일은 같은 메시지 키를 가져야 합니다. 영어 파일의 일부는 다음처럼 작성할 수 있습니다. json { "extensionName" : { "message" : "Simple Side Note" }, "extensionDescription" : { "message" : "A private notepad in your browser sidebar" }, "addToMemo" : { "message" : "Add to Memo" } } 한국어 파일은 키를 유지하고 message 만 번역합니다. json { "extensionName" : { "message...

Android RxJava Polling을 Kotlin Flow로 바꾸기: repeatOnLifecycle과 재시도

이미지
이 글은 기존 Android Retrofit2 RxJava polling: 일정 간격으로 API 호출하기 와 짝을 이루는 마이그레이션 가이드입니다. RxJava로 구현된 polling을 Kotlin Flow와 repeatOnLifecycle 로 옮기는 과정을 실행 가능한 코드로 다룹니다. Android RxJava Polling을 Kotlin Flow로 바꾸기: repeatOnLifecycle과 재시도 이미 RxJava로 polling을 구현한 프로젝트에서 Kotlin Coroutines와 Flow로 옮기면 구조화된 동시성, 자연스러운 취소 처리, 생명 주기 연동을 더 단순하게 만들 수 있습니다. 이 글에서는 RxJava 3 polling 코드를 Kotlin Flow로 단계별로 바꾸고, 화면 생명 주기와 안전하게 연결하는 방법을 다룹니다. 핵심 질문 이 글의 답 RxJava interval 은 Flow로 어떻게 바꾸나? flow + delay 또는 while().emit().delay() 루프 switchMapSingle 은 Flow로 어떻게 표현하나? 가장 최신 결과만 남기는 transformLatest / mapLatest 오류로 polling이 끊기지 않게 하려면? 요청 내부에서 예외를 상태로 변환, retryWhen 으로 지수 백오프 화면이 사라지면 자동으로 멈추려면? repeatOnLifecycle(STARTED) 에서 수집 테스트는 어떻게? runTest , TestDispatcher , 가짜 Repository 왜 Flow로 바꾸는가 RxJava는 여전히 강력한 라이브러리지만, 새 Kotlin 프로젝트에서는 다음 이유로 Coroutines/Flow가 자연스러운 선택이 됩니다. 비교 RxJava 3 Kotlin Flow 취소 전파 Disposable 수동 관리 구조화된 동시성(부모-자식) 생명 주기 연동 LiveData / Lifecycle ...

Android RecyclerView에서 Jetpack Compose LazyColumn으로 이전하기: ViewBinding·ListAdapter 비교

이미지
Android RecyclerView에서 Jetpack Compose LazyColumn으로 이전하기 기존 XML 화면의 RecyclerView , ViewBinding , ListAdapter 를 Jetpack Compose로 옮길 때 가장 중요한 변화는 어댑터를 새 문법으로 바꾸는 것 이 아닙니다. ViewHolder가 화면 상태를 직접 갱신하던 구조를 버리고, 하나의 UI 상태를 Composable 함수에 전달하는 구조로 바꾸는 것이 핵심입니다. 이 글에서는 즐겨찾기 가능한 사용자 목록을 예제로 다음 과정을 한 번에 연결합니다. ListAdapter 와 DiffUtil 을 LazyColumn 의 items() 로 전환 ViewModel 의 StateFlow 를 생명주기에 맞게 수집 안정적인 key 로 스크롤 위치와 아이템 상태 보존 로딩·빈 목록·오류·정상 목록을 하나의 상태 모델로 처리 기존 Fragment에 ComposeView 를 넣어 화면을 단계적으로 이전 Compose UI 테스트로 클릭 결과 확인 이 글은 2026년 7월 Android 공식 문서를 기준으로 작성했습니다. Compose와 AndroidX 버전은 고정 숫자를 복사하기보다 프로젝트의 최신 안정 Compose BOM과 공식 릴리스 정보를 확인하세요. RecyclerView와 LazyColumn은 무엇이 다른가 둘 다 화면에 보이는 항목 중심으로 UI를 구성하므로 긴 목록에 적합합니다. 그러나 개발자가 관리하는 책임은 크게 다릅니다. RecyclerView 기반 구현 Compose 기반 구현 달라지는 책임 XML 아이템 레이아웃 @Composable 아이템 함수 레이아웃과 바인딩 로직을 Kotlin 함수로 통합 RecyclerView.ViewHolder 별도 객체 없음 현재 상태를 받아 UI를 선언 ListAdapter LazyColumn 목록 배치와 지연 구성 담당 DiffUtil.ItemCallback ...