Hyeyeon blog

[Android] Kotlin - Coroutine with Retrofit2 본문

개발/Android

[Android] Kotlin - Coroutine with Retrofit2

Hyeyeon.P 2018. 12. 31. 18:54
반응형

# 서브루틴

- [단일 지점 시작] ---> [특정 지점 종료]

# Coroutine [Github]

- [단일 지점 시작] ---> [임의 지점 멈춤] ---> [해당 지점 재개] ---> [특정 지점 종료]

- 함수 실행 중 나갔다가 나중에 필요할 때 해당 시점으로 다시 돌아와서 재개 가능

- sequencial code를 통해 non-blocking 코드를 작성하기 위한 수단

- 비동기 처리 라이브러리

- 메인 루틴과 서브루틴이 종속적이지 않고 대등한 관계(cooperative)를 가짐

suspend 키워드로 마킹된 함수를 CPS(Continuation Passing Style)로 변환하고, 이를 Coroutine Builder를 통해 적절한 스레드 상에서 시나리오에 따라 동작하도록 구성

* CPS : '인수인계' 개념 (Labeling 사용) 

* 실행 순서는 Statemachine이 관리 (label 순으로 실행)

1. Suspending function

- 코루틴의 실행을 지연시킴

- suspending function을 생성할 경우, fun 앞에 suspend를 붙여 선언 

- suspending function 안에서 또다른 suspending function 호출 가능

- coroutine builder 안에서만 호출 가능

- delay: 코루틴에서 제공되는 suspending function으로, 스레드를 blocking하지 않고 코루틴을 delay 시킴 

2. Coroutine builder

- runblocking : 새로운 코루틴을 launch하고 코루틴이 완료될때까지 현재 스레드를 block

- launch : 새로운 코루틴을 launch하고 코루틴의 참조를 job Object로 반환

- async: 새로운 코루틴을 launch하고 코루틴의 참조를 Deferred<T> Object로 반환

class SimpleCoroutinesActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        //init stuff
        
        fab.setOnClickListener {
            launch(UI) {
                setTextAfterDelay(2, "Hello from a coroutine!")
            }
        }
    }

    private suspend fun setTextAfterDelay(seconds: Long, text: String) {
        delay(seconds, TimeUnit.SECONDS)
        textView.text = text
    }
}


# Coroutine With Retrofit2

1. .gradle

 * Retrofit2와 함께 사용하기위해 추가 [Github]

 * Kotlin 1.3부터 포함되어 있어 coroutine 라이브러리를 추가하지 않고 사용 가능

implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'

2. Service.kt

* Exception은 try-catch 구문으로 처리

@GET("api.json")
fun getResponse(@Query("param") param: Int): Deferred<List<Item>>

3. Repository.kt

override fun getResponse(param : Int): Deferred<List<Item>> =   GlobalScope.async(Dispatchers.Default, CoroutineStart.DEFAULT, null, {        dataSource.getResponse(param).await() })

4. Repository 호출

GlobalScope.launch(Dispatchers.Default, CoroutineStart.DEFAULT, null, {
  try {
    val response = repository.getResponse(param).await()
    ...
  } catch (e: Exception){
    println("Catch Exception")
  }
})


[참고 및 출처]

[KotlinConf 2018 - Kotlin Coroutines in Practice by Roman Elizarov]

[Kotlin Coroutines in Android]

[DroidKnights 2018]

[RxJava와 Kotlin Coroutines 비교해보기]

728x90

'개발 > Android' 카테고리의 다른 글

[Android] Dependency Injection vs Service Locator  (0) 2019.01.22
[Android] Floating Button size  (0) 2019.01.17
[Android] TextInputLayout  (0) 2019.01.17
[Android] Kotlin - Realm  (0) 2019.01.11
[Android] Kotlin - Firebase Dynamic Link  (0) 2019.01.10
Comments