Sadturtleman

로그 출구가 셋이면 아무도 못 찾는다: 안드로이드 관측 파이프라인 합치기

앱에 Timber, AnalyticsLogger, CrashReporter 세 개의 로그 출구가 있었다. 각각 게이트도 포맷도 달라서 이 로그가 왜 안 찍히는지에 답할 방법이 없었고, 성능 지표는 아예 없었다. 이걸 관측 파이프라인 하나로 합치면서 배운 것을 정리한다. 게이트를 어디에 두느냐가 성능과 추적성을 동시에 결정했다. 작업한 코드는 RuleU...

글로벌 서비스라면 GMS부터 확인하라: FCM과 지오펜스가 조용히 죽는 기기들

FCM 푸시 인프라를 설계하다가 당연하게 여기던 전제를 다시 보게 됐다. FCM은 안드로이드 기능이 아니라 GMS(Google Mobile Services) 기능이다. 우리 앱은 이미 지오펜스를 쓰고 있고 FCM과 Play Integrity를 추가할 예정인데, GMS가 있는 기기인지 확인하는 코드는 한 줄도 없었다. 국내 타깃이라면 큰 문제가 아닐 수...

WorkManager 주기 폴링 실전: 명시적 초기화, 동적 주기, 그리고 네트워크가 꺼져 있을 때

습관 인증 앱을 만들면서 기기에서 모은 인증 신호를 주기적으로 서버에 보내는 백그라운드 폴링을 WorkManager로 구현했다. 단순해 보이는 요구사항인데 실제로는 세 가지 벽에 부딪혔다. 초기화를 왜 명시적으로 해야 하는가, 폴링 주기를 왜 하나로 고정하면 안 되는가, 서버에 의존하는 폴링은 무엇이 위험한가. 이 글은 팀 전송 테크 스펙(§0.x로 ...

딥링크가 화면을 안 바꾼다? Android launchMode의 필요성과 4가지 종류, 고려사항

에뮬레이터로 앱을 검증하다가 이상한 버그를 만났다. 챌린지 생성 API는 200으로 성공했는데 화면은 확인 페이지에서 꼼짝하지 않고, 뒤에서는 홈 화면 API가 멀쩡히 재호출되고 있었다. dumpsys activity 를 열어보니 범인은 코드가 아니라 매니페스트에 없던 한 줄, launchMode 였다. 이 글은 그 버그를 계기로 launchMode가...

퍼포먼스 로깅이 필요한 이유와 사용 방법

“앱이 느린 것 같아요”라는 제보를 받으면 코드를 고치기 전에 어디가 얼마나 느린지를 숫자로 확인해야 합니다. 감으로 최적화하면 엉뚱한 곳을 고치고, 고친 뒤에도 좋아졌는지 확인할 방법이 없습니다. 이 글은 퍼포먼스 로깅이 왜 필요한지를 정리하고, 안드로이드에서 measureTimeMillis 부터 androidx.tracing, 프로덕션 모니터링까지...

안드로이드 이미지 업로드 OOM, 원본을 통째로 메모리에 올리지 마라

“갤러리에서 사진 하나 골라 업로드했을 뿐인데 저사양 기기에서 앱이 죽어요.” 사용자가 고른 이미지를 서버로 올리는 흔한 기능에서, 무심코 짠 코드가 OutOfMemoryError의 원인이 되는 경우가 많습니다. 이 글은 제가 작업 중인 안드로이드 앱(RuleUp-ASM/Android)에서 이미지 업로드 경로를 손보며 정리한 내용입니다. 원본을 통째로...

백프레셔가 왜 중요한가, 안드로이드 MVI 코드로 보는 네 가지 전략

“버튼을 빠르게 두 번 누르면 같은 화면이 두 번 열려요.” “스크롤할 때 로그가 폭주해서 UI가 버벅여요.” 이런 버그의 뿌리에는 거의 항상 백프레셔(backpressure) 문제가 있습니다. 이벤트를 만드는 쪽이 처리하는 쪽보다 빠를 때, 그 속도 차이를 어떻게 다룰지 정해두지 않으면 메모리가 새거나 이벤트가 밀리거나 화면이 멈춥니다. 이 글은 백...

온보딩에서 유저 정보와 버전 체크가 꼭 필요한 이유

앱을 켜면 가장 먼저 보이는 화면, 온보딩 단계에서는 보통 두 가지를 확인합니다. 유저 정보(로그인 상태, 약관 동의, 프로필 완성 여부)와 앱 버전입니다. 바로 메인 화면을 띄우면 안 되나 싶지만, 이 두 체크를 건너뛰면 나중에 더 비싼 비용을 치릅니다. 이 글은 둘을 왜 온보딩에서 가장 먼저 처리해야 하는지 정리합니다. 왜 유저 정보를 먼저 확인...