Android 정확한 타이머 앱 구현하기 (CountDownTimer의 한계와 기준 시각 설계)

시험 타이머, 운동 타이머, 집중 타이머 같은 앱을 개발할 때 초보자가 가장 많이 하는 실수가 있습니다. 바로 화면에 보이는 카운트다운 숫자를 그대로 '타이머의 진짜 상태'라고 믿고 설계하는 것입니다. 저의 경우에도 처음에 CountDownTimer 나 코루틴 delay(1000) 를 사용해서 1초마다 숫자를 단순히 줄이는 방식으로 구현했었습니다. 하지만 이렇게 하면 앱이 백그라운드로 가거나, 화면이 회전되거나, 시스템에 의해 프로세스가 종료되었을 때 시간이 완전히 틀어지는 문제가 발생하더라고요. 타이머 앱을 안정적으로 운영하려면 "1초마다 숫자를 줄이는 방식"이 아니라 "언제 시작했고 언제 끝나야 하는지" 기준 시각을 저장하는 방식으로 접근해야 합니다. 나중에 제가 다시 개발할 때 참고하기 위해 핵심 설계 구조와 구현 코드를 정리해 둡니다. 1. 타이머 구현 시 자주 겪는 문제들 단순히 UI의 Tick 값만 믿고 개발하면 아래와 같은 실무 문제에 부딪히게 됩니다. CountDownTimer 가 돌던 중 화면을 회전하면 Activity가 재생성되면서 타이머가 처음부터 다시 시작됨 사용자가 홈 버튼을 눌러 앱이 백그라운드로 간 동안 코루틴이나 타이머가 멈춰서 시간이 안 감 기기 시스템 시각을 사용자가 수동으로 바꾸거나 해외 로밍 등으로 네트워크 시간이 동기화되면 남은 시간이 비정상적으로 계산됨 일시정지(Pause)와 재개(Resume)를 반복할 때 오차가 누적됨 결론부터 말씀드리면, 타이머는 단순한 UI 카운트다운 인터페이스가 아니라 '상태 머신'과 '시간 계산 로직'의 결합 으로 바라보고 설계해야 합니다. 2. 핵심 개념: '틱(Tick)'이 아니라 '기준 시각' 저장하기 타이머의 남은 시간은 저장된 고정 값이 아니라 "현재 시점 기준으로 매번 계산하는 결과"여야 합니다. 이를 위해 필요한 핵심 데이터 모델은 다음과 같습니다. 항목 의...

관광 앱 상세 화면 만들 때 놓치는 데이터 검증과 정보 구조 설계 기준

제주에서 이런저런 가이드 앱이나 유틸리티 서비스를 만들고 운영하다 보면, 결국 가장 손이 많이 가고 컴플레인이 자주 들어오는 곳이 바로 상세 화면(Detail View)입니다. 처음에는 공공데이터 API 땡겨와서 응답 나오는 대로 대충 뿌려주면 끝날 줄 알았는데, 실제 운영해보면 데이터가 대화면에 찍히는 것과 사용자가 그걸 믿고 실제 방문 결정을 내리는 것은 완전히 다른 문제더군요. 공공데이터는 설명문, 이미지, 운영 시간의 출처가 제각각이거나 갱신 주기가 달라서 관리를 까먹으면 바로 버그성 화면이 되기 십상입니다. 나중에 제가 다시 개발할 때 참고하려고 상세 화면의 정보 구조 설계, 데이터 기준일 처리, HTML 정제, 보안 체크리스트까지 실무 기준으로 짧고 명확하게 정리해 둡니다. 1. 내가 겪은 문제: API 응답을 그대로 나열할 때의 한계 공공데이터나 외부 API 응답 필드를 아무 생각 없이 데이터 바인딩해서 UI에 그대로 때려 넣으면 아래와 같은 문제가 무조건 터집니다. 사용자가 진짜 지금 보고 싶어 하는 정보(운영 여부, 주소, 전화번호)가 긴 소개글에 묻힘. 데이터가 비어 있을 때(Null) 화면이 툭 끊기거나 뜬금없는 공백이 생김. 공공데이터의 기괴한 HTML 태그( <br> , &gt; 등)가 화면을 깨뜨리거나 웹뷰 보안 취약점을 만듦. 공개하면 안 되는 내부 API URL, 지도 API Key, 사용자 좌표가 로그나 소스코드에 섞여 들어감. 결국 상세 화면은 단순한 '데이터 표시 창'이 아니라, 사용자가 방문 판단을 내리는 신뢰 화면 으로 접근해야 구조가 안정적으로 잡힙니다. 2. 해결 방법 1: 화면 전용 UI 모델(UiModel) 분리 API 응답 모델(DTO)을 Activity나 Fragment, 또는 Compose 스크린에 그대로 던지지 마세요. 무조건 화면 표시용 독립 모델 을 따로 파서 파싱하는 게 유지보수에 정신 건강을 이롭게 합니다. Kotlin data class TourDetailUiMo...