Lifecycle 에 맞춰 RxJava Stream 재실행하기

SeongUg Steve Jung
Aug 6, 2019 · 4 min read

오랜만에 개발 글을 쓰려고 돌아왔습니다.

오늘 쓰려는 내용은 Android Lifecycle 에 맞춰서 Observable/Single… 등등의 RxJava Stream 을 실행, 종료 그리고 재실행 하도록 하는 코드를 만들어보려고 합니다

RxJava Stream 실행 관리가 필요한가?

RxJava 를 사용함에 있어서 가장 유의할 사항은 dispose 처리를 제때 해주어 화면이 종료되어도 RxJava Stream 이 컴퓨팅 리소스를 사용하지 않도록 해주는 것입니다.

그렇기 때문에 수많은 라이브러리들이 특정시점에 자동으로 종료되도록 하고 있습니다.
이러한 목적으로 나온 라이브러리들이 Trello 의 RxLifecycle, Uber 의 AutoDispose 등이 있습니다.

하지만 이러한 라이브러리들은 동작이 시작된 Stream 에 한해서 Dispose 관리를 하고 있습니다. 그러한 경우도 기존 라이브러리들이 대체를 하고 있지만 한가지 단점이 있습니다.

이러한 코드는 Lifecycle 의 PAUSE 를 만나게 되면 종료되지만 RESUME 이 되었을 때 재실행하지 못하기 때문에 onResume 에 맞춘 코드에서 요청하도록 해야합니다.

그래서 오늘 하고자 하는 것은 특정 실점에 자동으로 스트림을 실행하고 종료하는 코드를 만들어보고자 합니다.

첫번째로 Lifecycle 에 맞춰서 콜백을 실행하는 코드를 만들고자 합니다.

위와 같이 간단하게 Lifecycle 리스너를 관리해주는 중앙 관리자 하나 만들도록 할 것입니다.

LifefcycleController : 라이프사이클을 관리해주는 Manager 클래스
LifecycleObserver : 라이프사이클 콜백을 받는 클래스

RxLifecycleObserver 는 재실행가능한 Stream 을 실행하고 종료하도록 하기 위해 이를 메모리에 저장하도록 할 것입니다.

위의 코드에서 onInit, onVisible 은 실제로 Observable.create().subscribe() 를 실행할 수 있는 함수객체를 저장하고 시점에 맞춰서 실행하도록 할 것입니다.

그리고 initDisposable, visibleDisposable 은 실행한 Stream 을 종료를 제어할 수 있는 변수를 관리하고 시점에 맞춰서 종료하도록 할 것입니다.

이제 Controller 를 Activity 에 정의하고 이를 ViewModel 에 공유하도록 하여 Activity 가 ViewModel 에 직접 콜백을 정의하지 않아도 ViewModel 이 가진 Controller 를 통해서 자동으로 실행 종료하도록 하겠습니다.

RxLifecycle 생성 코드의 가독성을 높이기 위해 아래와 같이 코드를 추가하도록 하겠습니다.

변경 후의 코드는 좀 더 명시적으로 onInit 시점에 맞춰서 동작할 것임을 알 수 있습니다.

LifecycleController 에 Observer 를 등록하는 과정에서 반복된 코드를 수정하기 위해 아래와 같이 코드를 추가하도록 하겠습니다.

위의 코드에서 LifecycleObserver.unarayPlus()+LifecycleObserver를 의미하며 +onInitLifecycleController.addObserver(onInit()) 을 축약한 표현이라 보면 됩니다.

종합

RxJava 를 통해서 Lifecycle 에 따라 종료하는 것은 기존에도 많은 예제들이 있지만 이를 재실행하기 위한 코드들은 관습대로 Activity 에서 ViewModel 을 재호출하도록 하는 코드들이 많습니다. 오늘의 코드는 onResume <-> onPause 가 반복되는 상황에서 어떻게 RxJava Stream 을 실행하고 종료할 수 있는지를 알아보았습니다.

최종적으로 기존의 코드들은 아래와 같이 바뀔 수 있습니다.

// 기존
class MainViewModel(delegate: LifecycleDelegate) {
fun onResume() { Observable.compose(delegate).subscribe() }
}
// 변경
class MainViewModel(delegate: LifecycleDelegate): LifecycleDelegate by delegate {
init {
+onVisible { Observable.subscribe() }
}
}

Sample Project : 전체 샘플코드
Jetpack Compose AOSP : unary 사용법

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store