pile·
모바일·티몬티몬·

티몬 안드로이드 앱 RxAndroid 적용 사례

티몬 안드로이드 앱에서 한 화면에 여러 API 응답을 순서대로 배치해야 하는 문제를 RxAndroid로 정리한 사례다. 플래그를 세워 모든 응답을 기다리던 코드가 API가 늘 때마다 복잡해지자 zip 연산자로 바꿨다. Observable 생성부터 스케줄러 지정, 구독 해제까지 단계별 코드가 붙는다.

핵심 포인트
  • 화면에 노출할 정보가 늘면서 비동기로 호출할 API가 많아졌고 뷰는 정해진 순서로 배치해야 했다.
  • 처음에는 응답마다 플래그를 세우고 매번 전체 플래그를 확인하는 방식이라 중복 코드가 쌓였다.
  • zip은 모든 Observable이 최소 한 번씩 아이템을 발행할 때마다 결합 함수를 실행한다.
  • 그래서 API 응답이 실패해도 빈 데이터를 담아 onNext를 호출해야 결합이 진행된다.
  • RxJava 2에서는 onNext에 null을 넘기면 예외가 나므로 빈 데이터임을 알 수 있는 아이템을 발행해야 한다.
  • subscribeOn은 구독이 실행되는 스레드를, observeOn은 그 뒤에 오는 연산자와 구독자를 바꾼다.
상세 정리
  • 배경: 초기에는 한 화면에서 같은 패턴의 목록과 배너 몇 개를 보여주는 단순한 구조였다.
  • 변화: 이벤트 배너와 가격 목록, 기획전 목록처럼 뷰가 다양해지면서 호출할 API가 늘었다.
  • 제약: 모든 API는 비동기로 호출하되 각 뷰는 정해진 순서에 맞게 배치돼야 했다.
  • 첫 구현: 모든 API를 호출하고 응답마다 플래그를 세운 뒤, 플래그가 바뀔 때마다 전체를 확인해 다 모였으면 순서대로 어댑터에 넣었다.
  • 첫 구현의 문제: 동작에는 문제가 없었지만 중복 코드가 많아지고 API가 추가될 때마다 신경 쓸 부분이 늘었다.
  • 1단계 Observable 만들기: 각 API 호출을 감싸 응답을 받으면 onNext와 onComplete를 부르는 Observable을 만들어 목록에 담는다.
  • 실패 처리: 응답을 정상적으로 받지 못한 경우에도 빈 데이터를 발행해 스트림이 끊기지 않게 한다.
  • 버전 차이: RxJava 1에서는 onNext에 null이 허용되지만 2에서는 NullPointerException이 나므로 빈 데이터 객체를 따로 두어야 한다.
  • 2단계 결합: Observable 목록을 zip으로 묶고 결합 함수에서 배열로 들어온 아이템들을 하나의 데이터 집합으로 가공해 구독자에게 넘긴다.
  • zip의 동작: 각 스트림이 한 번씩 발행할 때마다 결합 함수가 돌며 그 결과가 하나의 아이템으로 나간다.
  • 3단계 스케줄러: 구독 로직에 API 호출이 있으므로 subscribeOn에는 I/O에 적합한 스케줄러를, 이후 UI 작업이 있으므로 observeOn에는 메인 스레드를 준다.
  • 적용 범위의 차이: subscribeOn은 호출 순서와 무관하게 최상단 Observable에 적용되고, observeOn은 바로 다음에 오는 연산자부터 적용된다.
  • 클라이언트별 주의: 예제에 쓴 HTTP 클라이언트는 콜백을 메인 스레드에서 돌려주지만 클라이언트마다 다르므로 명시하는 편이 안전하다고 덧붙인다.
  • 4단계 구독: subscribe로 시작하고 onNext에서 받은 데이터로 어댑터를 세팅해 화면에 그린다.
  • 자원 정리: onSubscribe에서 받은 Disposable을 CompositeDisposable에 모아두고 화면이 소멸될 때 한꺼번에 비워 메모리 누수를 막는다.
  • 최종 형태: zip으로 묶고 스케줄러를 지정한 뒤 구독하는 네 줄의 체이닝으로 정리된다.
  • 도입 소회: 학습 곡선이 가파르고 참고 자료가 많지 않아 고생했으니 작은 부분부터 단계적으로 적용하기를 권한다.
왜 읽나여러 API 응답을 다 모아야 화면을 그릴 수 있는 구조에서 플래그 관리로 버티고 있다면 zip과 스케줄러 조합으로 정리하는 최소 형태를 볼 수 있다.
티몬
티몬 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 모바일·당근당근 테크블로그·

    웹뷰 다음의 레일을 깔다: 당근이 Lynx를 선택한 이유

    당근 프론트엔드코어팀이 WebView 기반 화면의 첫 프레임 렌더링 문제를 해결하기 위해 Lynx를 도입한 기록이다. 레퍼런스가 거의 없는 기술을 코드베이스 직접 분석으로 검증한 뒤 프로덕션에 적용했고, 1.9백만 사용자 A/B에서 Android 18%, iOS 37%의 첫 프레임 단축을 달성했다.

    요약 이어보기
    #cross-platform#webview#mobile-performance+2
  2. 모바일·토스 SLASH토스 SLASH·

    토스의 디바이스 팜 만들기

    토스가 각 팀이 각자 운영하던 작은 디바이스 팜을 하나의 중앙 플랫폼 '네뷸라(Nebula)'로 통합한 과정을 다룬다. Appium 대신 자체 드라이버를 개발해 클릭 13.5배, 텍스트 입력 10배의 성능을 달성했고, Android와 iOS 미러링도 직접 내재화해 실기기 원격 조작과 화면 실시간 공유를 동시에 가능하게 만들었다. 현재 100대를 넘어 수백 대를 향해 24시간 가동 중이다.

    요약 이어보기
    #android#ios#appium+2