• 목록 (128)
    • Android (62)
    • Back-End (2)
    • Java (3)
    • Kotlin (16)
    • CS (7)
    • 개발 서적 (12)
    • 문제 풀이 (26)

최근 글

티스토리

전체 방문자
오늘
어제
hELLO · Designed By 정상우.
MJ_94

한 우물만 파는 기술 블로그

[Kotlin] 코틀린에서 RxJava와 Coroutine
Kotlin

[Kotlin] 코틀린에서 RxJava와 Coroutine

2022. 1. 6. 13:01

위 두 라이브러리는 비동기 작업을 구현하는 방법으로 여기저기서 많이들 사용한다.
코틀린의 경우 RxJava와 Coroutine 모두 사용 가능하고, 두 방식을 혼합하여 사용할 수도 있다.

먼저 간단하게 두 방식 사용 방식 차이점에 대해 알아보자.

RxJava

RxJava는 Observable Pattern, Iterator Pattern, Functional Programming을 결합한 형태로 데이터를 관찰 가능한 stream 형태로 받을 수 있다. 그렇기 때문에 중간중간마다 데이터의 변화를 확인할 수 있다.

RxJava를 사용하기 위해서는 반환값으로 Single 클래스를 사용해야 한다.

interface UserService{

    @GET("/users)
    fun getUser(): Single<List<User>>

    @GET("/users/{userId}/age")
    fun getUserAge(@Path("userId") userId: Int): Single<Int>
}

 

Coroutine

코루틴에서는 위에서 설명한 RxJava와 비슷한 형태로 표현할 수 있고, suspend 함수를 사용할 수도 있다.
RxJava와의 차이점은 ObserverPattern이 아닌 데이터를 직접 함수 return 형태로 받는다.
Suspend 함수는 이름에서 유추할 수 있듯이 코드 실행을 일시중지했다가 나중에 함수가 완료되었을 때 다시 시작할 수 있는 함수다.

RxJava처럼 연쇄적인 처리가 필요할 경우는 Coroutine의 Flow 사용을 고려하면 되는데 Flow를 여기서 설명하지는 않겠다.

먼저 RxJava 형태와 비슷하게 Deferred 클래스를 사용해볼 수 있다.

interface UserService{

    @GET("/users)
    fun getUser(): Deferred<List<User>>

    @GET("/users/{userId}/age")
    fun getUserAge(@Path("userId") userId: Int): Deferred<Int>
}

이번엔 suspend 함수로 표현해보자.

interface UserService{

    @GET("/users)
    suspend fun getUsers(): List<User>

    @GET("/users/{userId}/age")
    suspend fun getUserAge(@Path("userId") userId: Int): Int
}

 

사용법

이렇게 각자의 방식으로 만들어진 UserService는 사용법 역시 차이점이 있다.

RxJava의 경우 앞서 말한 스트림으로 부터 데이터를 통지받기 위해 subscribe 처리가 필요하다.

class viewModel(private val service: UserService): ViewModel(){
    private val disposable = CompositeDisposable()

    fun getUserData(){
        disposable +=
            service.getUser()
                   .subscribeOn(io())
                   .observeOn(mainThread())
                   .subscribe({ users ->
                           updateUI(users)
                   }, { error ->
                           updateUI(error)
                   })

    }

    private fun updateUI(reponse: Any){
        ...
    }

    override fun onCleared(){
        disposable.clear()
    }
}

 

코루틴의 경우 suspend 함수를 사용한다면 아래와 같이 좀 더 깔끔한 코드를 만들 수 있다.

class viewModel(private val service: UserService): ViewModel(){

    fun getUserData(){
        viewModelScope.launch{
            runCatching{
                val users = service.getUsers()
                updateUI(users)
            }.getOrElse{ tr ->
                updateUI(tr)
            }
        }
    }

    private fun updateUI(reponse: Any){
        ...
    }
}

 

RxJava와 Coroutine의 차이점

[RxJava]

  • Observable Pattern으로 구독
  • 구독 시작 후 Stream형태로 데이터들이 들어옴
  • 중간마다 Stream을 통해 데이터의 변경을 확인 가능

[Coroutine]

  • 비교적 간단한 함수들을 사용한다.
  • 데이터가 return 되기 전까지 대기한다.
  • 처리가 끝나 return한 데이터로 그다음 처리가 가능하다.
저작자표시 비영리 변경금지 (새창열림)

'Kotlin' 카테고리의 다른 글

[Kotlin] Delegation  (0) 2022.03.22
[Kotlin] 코틀린의 시퀀스(Sequence)  (0) 2022.01.24
[Kotlin] Coroutine 동기화 처리  (0) 2021.12.21
[Kotlin] inline 함수  (0) 2021.09.06
[Kotlin] Flow  (0) 2021.08.13
    'Kotlin' 카테고리의 다른 글
    • [Kotlin] Delegation
    • [Kotlin] 코틀린의 시퀀스(Sequence)
    • [Kotlin] Coroutine 동기화 처리
    • [Kotlin] inline 함수
    MJ_94
    MJ_94
    안드로이드, 개발 관련 기술 블로그

    티스토리툴바