/ GDG, ANDROID, RXJAVA, RXANDROID

GDG Korea Android Weekly - 2월 1주차

GDG Korea Slack#android 채널에서 오고간 주제를 정리한 포스트 입니다. 가입은 여기에서 하실 수 있습니다.

RxJava/RxAndroid

Rx 스터디

최근 RxJava/RxAndroid에 대한 관심이 매우 높고, 현업에서 이를 사용하는 사례도 꽤 많습니다. 하지만, 이와 관련된 스터디나 행사가 잘 없어 다양한 사람들이 각각 어떤 방식으로 사용하는지 알기 어려웠습니다.

이러한 아쉬움을 해소하기 위해 ‘RxJava/RxAndroid 사용자 모임’이 근 시일 내에 개최될 예정입니다. 자세한 행사 일정이 나오게 되면 별도로 공지될 예정이니 관심 있으신 분들께서는 기대하셔도 좋을 것 같네요.

MissingBackpressureException

MissingBackpressureExceptionObservable에서 항목(item)을 보내는(emit) 속도보다 처리하는 속도가 느릴 때 발생합니다.

RxJava 가이드 문서 내 Backpressure 항목에도 이와 관련된 항목이 기술되어 있는데, 문서에서 예로 든 사례(zip 연산자를 사용하는 경우)를 사용하지 않는 경우에도 상당히 높은 확률로 경험할 수 있습니다.

RxAndroid를 사용하는 경우, 수신된 데이터를 UI에 표시하기 위해 observeOn(AndroidSchedulers.mainThread()) 를 많이 사용합니다. 그런데, 이 과정에서 UI 쓰레드 내에서 다른 작업이 수행되고 있어 Observable에서 보낸 항목을 바로 처리하지 못할 경우 MissingBackpressureException이 발생합니다. 따라서, 항상 발생하지 않고 사용자 환경에 따라 발생 여부가 달라질 수 있는 부분이라 개발 도중에는 발견하지 못할 가능성도 매우 높습니다.

위 오류를 방지하려면 Backpressure가 필요할 때 처리할 방법을 다음과 같이 지정해 주면 됩니다.

  • onBackpressureBuffer(): Observable에서 보낸 항목을 큐에 계속 쌓아두어, 항목을 처리하는 쪽에서 해당 항목을 나중에 처리할 수 있도록 합니다. 항목이 무한정 쌓이는 것을 방지하기 위해 onBackpressureBuffer(int) 를 사용하여 큐에 쌓아둘 수 있는 항목 수를 제한할 수도 있습니다.
  • onBackpressureDrop(): Observable에서 항목을 보냈을 때 바로 처리되지 못한 데이터는 무시합니다. 서버나 데이터베이서에서 받은 데이터를 처리할 때 이 방법을 사용하면 실제로 받은 데이터와 UI에 표시되는 데이터 간 차이가 발생할 수 있으니 신중하게 사용해야 합니다.

subscribeOn / observeOn

작업이 수행될 쓰레드를 지정하기 위해 subscribeOn()observeOn() 메서드를 사용하는데, 역할은 비슷하지만 각각 적용되는 효과가 조금 다릅니다.

  • subscribeOn: 작업을 시작하는 쓰레드를 지정합니다. 체인의 어느 곳에 사용해도 가장 마지막에서 지정해 준 것만 적용됩니다.
  • observeOn: 바로 다음 번에 실행되는 연산이 실행되는 쓰레드를 지정합니다. 이를 사용하여 하나의 체인 내에서 실행되는 여러 연산들이 수행될 쓰레드를 각각 지정할 수 있습니다. 안드로이드에서 사용할 경우, 일반적으로 subscribe() 직전에 observeOn(AndroidSchedulers.mainThread()) 를 사용하여 onNext() 메서드가 UI 쓰레드에서 실행되도록 구성합니다.

공식 문서 내 Scheduler 항목에 포함되어 있는 아래 그림을 보시면 좀 더 이해가 쉽습니다.

Schedulers

flatMap / concatMap

두 연산자는 Observable 에서 받은 항목을 다른 형태로 변형해 준다는 점은 동일하지만, 세부 동작이 하나 다릅니다. 빠른 이해를 위해 공식 문서 내 포함되어 있는 각 연산자별 설명 이미지를 보겠습니다.

[flatMap] flatMap

flatMap은 아밴트 스트림에서 발생한 항목들을 처리할 때 merge 연산자를 사용합니다. 따라서 이벤트 스트림에서 항목이 인입됨과 동시에 결과를 출력합니다.

이러한 특성 때문에, 인입되는 항목 순서와 출력되는 순서가 달라질 수 있습니다. 위의 예 에서도 초록색과 파란색 항목의 순서가 섞여 출력되는 것을 확인할 수 있습니다.

[concatMap] concatMap

concatMap은 이벤트 스트림에서 발생한 항목들을 처리할 때 concat 연산자를 사용합니다. 때문에 flatMap과는 달리 이벤트 스트림을 통해 전달된 항목 하나에 대한 처리가 완료된 후에 다음 항목을 처리합니다. 초록색 항목과 파란색 항목의 순서도 뒤바뀌지 않고 그대로 출력되는 것을 확인할 수 있습니다.

flatMap은 저도 상당히 많이 쓰는 연산자 중 하나인데, 위와 같은 차이점이 있었는지 이제야 알게 되었습니다. 순서가 섞이면 안 되는 연산에는 필히 concatMap을 사용해야겠습니다.

위와 관련하여 잘 정리된 블로그 포스트가 있으니, 추가 정보가 필요하신 분은 참고하세요.

RxJava Observable transformation: concatMap() vs flatMap() Link

RxMarbles

RxMarbles

RxMarbles 에선 Rx에서 사용하는 연산자가 어떤 방식으로 처리되는지 인터랙티브 형태로 확인할 수 있습니다.

이벤트 스트림에서 발생한 각각의 이벤트들을 직접 조작할 수 있어, 그림만으로는 이해가기 어려웠던 연산자들의 동작 방식을 좀 더 잘 이해할 수 있습니다. 이해가 잘 가지 않는 연산자가 있었다면, 이 기회에 확실하게 이해해 보는 것은 어떨까요?

Frodo

Frodo

Frodo는 RxJava의 디버깅을 도와주는 도구입니다. onSubscribe(), onNext(), onError(), onCompleted() 등 각 절차가 어떤 순서로 발생하는지, onNext()에서 발생한 데이터가 어떻게 되는지 쉽게 확인할 수 있습니다.

RxJava를 처음 배울 때 이 도구를 알았더라면 삽질하는 시간을 좀 더 줄일 수 있었을텐데, 참 아쉽습니다. 처음 접하는 사용자부터 어느 정도 익숙해진 사용자까지, RxJava를 사용하는 개발자에게 강력 추천해 주고 싶은 도구입니다.

Rx와 관련된 더 많은 읽을거리

Going Reactive, And Android Architectural Journey

RxAndroid의 창시자 Matthias Käppler의 발표 영상으로, Rx를 사용하여 안드로이드 애플리케이션을 개발한 경험에 대해 소개하고 있습니다.

Realm Korea 블로그에 발표 내용을 한글로 번역한 포스트가 올라와 있으니 함께 보시면 더 도움이 될 것입니다.

Android Application Architecture (번역)

RxJava를 사용하여 MVP 기반 구조를 설계하는 과정을 소개한 원문 포스트를 번역한 글입니다. RxJava를 실제로 사용하는 방법과, 이를 효율적으로 사용하기 위한 설계 팁을 함께 얻을 수 있겠네요.

기본적인 액티비티와 AsyncTask 에서 시작하여 RxJava 로 만든 MVP 기반 구조까지의 여정. Link

Android Studio

Android Studio 2.0 Beta 2가 공개되었습니다. Beta 1이 공개된 직후 큰 버그가 있어, 얼마 지나지 않아 바로 Beta 2가 나오는 우여곡절을 겪기도 했습니다.

Android Studio 2.0 Beta Available in Canary Channel - Android Tools Project Site Link

주요 변경 사항은 다음과 같습니다.

  • 성능 개선
  • Incremental Java complication과 Annotation processor를 사용하는 라이브러리 간 충돌 방지
  • Instant Run 관련 오류 수정
  • 개선된 에뮬레이터
  • 더 빨라진 ADB: 애플리케이션 설치 및 파일 전송 속도 최대 5배 향상

자세한 내용은 블로그 포스트를 참조하세요.

안녕… Otto

안드로이드에서 이벤트 버스(Event Bus)를 구현하는 라이브러리 중 대표격인 Otto의 지원이 공식적으로 중단 되었습니다.

Deprecate Otto in favor of RxJava by swankjesse · Pull Request #181 · square/otto Link

지원 중단을 알리면서 추가된 문서에는 Otto 대신 RxAndroidRxJava를 사용하라고 하는데요, 이런 것을 보면 역시 Rx는 거스를 수 없는 대세인가 봅니다.

삼성 스마트 매니저

삼성의 최신 펌웨어와 함께 배포되고 있는 스마트 매니저, 배터리 사용량을 비약적으로 절감하여 일반 사용자에게는 큰 호평을 받고 있으나 개발자에게는 큰 골칫덩어리가 되고 있습니다.

안드로이드 6.0부터 도입된 Doze mode와는 달리, 스마트 매니저를 통해 절전 상태에 들어간 애플리케이션의 경우 애플리케이션을 실행하거나 수동으로 절전을 하제하지 않는 한 GCM을 포함한 어떠한 방법으로도 해제가 불가합니다.

현재까지 서드파티 애플리케이션에서 직접 스마트 매니저의 절전 정책을 조정할 수 있는 방법은 없는 것으로 알려져 있으며, 통신사 애플리케이션이나 유명 메신저 앱 등만 화이트리스트에 포함되어 있어 개발사에서 직접 고객들에게 스마트 매니저와 관련된 사항을 공지해야 하는 등 불편이 속출하고 있습니다.

심지어 말랑스튜디오에서는 스마트 매니저를 막는 유틸리티를 제작하여 공개하기도 하였습니다.

malangstudio/AvoidSmartManager Util for avoid Samsung SamrtManager. Fucking SmartManager! Link

아무 애플리케이션에서 쓸 데 없이 자원을 사용하는 것을 막는다는 취지 자체는 좋으나, 이러한 정책을 개발사에서 조금 더 유연하게 적용할 수 있도록(예: Android 6.0부터 도입된 권한 다이얼로그와 같이 절전 활성화 여부를 묻는 다이얼로그를 띄울 수 있게 하는 등) 지원하면 훨씬 좋을 것 같습니다.

대화에 직접 참여하고 싶으신가요? GDG Korea Slack#android 채널을 방문하세요. 아직 가입하지 않으셨나요?

kunny

커니

안드로이드와 오픈소스, 코틀린(Kotlin)에 관심이 많습니다. 전 한국 GDG 안드로이드 운영자 및 GDE 안드로이드로 활동했으며, 현재 구글에서 애드몹 기술 지원을 담당하고 있습니다.

Read More