Home Coroutine에서 Retrofit 사용 시 알아둘 점
Post
Cancel

Coroutine에서 Retrofit 사용 시 알아둘 점

이전에 안드로이드 앱을 구현하면서 Coroutine에서 Retrofit을 사용한 적이 있었다. 그때 당시에는 인터넷 예제에서는 대부분 아래와 같이 구현되어 있었다.

1
2
3
4
interface XXXService {
    @GET("api/YYYY")
    suspend fun getData(): Call<ZZZZ> // 또는 Response<ZZZZ>
}

그런데, 레트로핏 2.6.0 이상부터는 코틀린 전용 확장 함수를 지원함으로써 Call 또는 Response를 해줄 필요가 없다고 한다. 그 이유를 추측해보자면 코루틴을 사용하기 전에는 스레드에서 데이터를 UI로 보낼 때에는 콜백함수를 이용해서 메인 스레드에 전달 해주어야 하기 때문에 Call로 랩핑을 해주어야 하지만, 코루틴은 콜백함수 없이도 suspend 키워드가 있다면 Dispatchers.Main에서도 UI에서 실행할 수 있기 때문인 것 같다.
만약 응답의 전체 데이터를 원한다면 Result<ZZZZ> 형식으로 사용 가능하다고 한다.

또한, 여러 인터넷에 있는 예제들을 보면 아래와 같이 구현된 것들도 가끔가다 볼 수 있었다.

1
2
3
4
5
6
7
8
suspend fun getResult() {
    viewModelScope.launch {
        withContext(Dispatchers.IO) {
            val data = XXXService.getData()
            // ...
        }
    }
}

이또한 잘못 사용한 예로 볼 수 있다. 위에서 언급한 것과 비슷하지만, viewModelScope의 내부를 살펴보면 디스패처가 Dispatchers.Main.immediate로 되어있는 것을 알 수 있다.

1
2
3
4
public val ViewModel.viewModelScope: CoroutineScope
// ...
CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
// ...

즉, 어차피 디스패처가 Main으로 설정되어 있고, 위에서 언급한 것처럼 레트로핏은 코루틴 관련 확장 함수들(suspend)을 지원하도록 구현되었으므로 굳이 코루틴에서 withContext를 실행해줄 필요가 없다.

아래는 구글 코드랩에 작성된 글을 가져왔다.

image


내 생각

코루틴에서 Dispatchers.IO는 네트워크 통신 등에서 사용될 수 있다고 하는데 아마 레트로핏을 이용하지 않고 HttpUrlConnection이나 다른 동기적으로 네트워크 통신을 하는 라이브러리를 이용해 직접 구현할 때를 의미하는 것 같기도 하다. 이 부분에 대해서는 좀 더 생각을 해봐야할 것 같다.


[출처]

  • https://developer.android.com/codelabs/kotlin-coroutines#8
This post is licensed under CC BY 4.0 by the author.

Coroutine 원리

Coroutine 취소 및 예외처리

Comments powered by Disqus.