Language/Kotlin

Language/Kotlin

Coroutines Dispatcher 알아보기

이번 글은 저번 CoroutineContext와 CoroutineScope를 소개한 것에 이어서 Dispatcher에 대해 알아보겠다. Dispatcher의 역할Dispatcher는 해당 코루틴이 어느 스레드나 스레드 풀에서 실행될지 결정한다. Dispatcher의 종류Dispatcher는 이미 정의된 몇가지가 있는데 이에 대해 짧막하게 알아보자. Dispatchers.MainMain Dispatcher는 오직 UI가 있는 애플리케이션에서만 사용할 수 있다. 안드로이드의 경우, UI 작업을 오직 메인 스레드에서만 허용하므로Main Dispatcher를 사용해 메인 스레드에서 실행할 수 있다. 해당 Dispatcher가 Main Looper와 연결된 Handler를 사용하기 때문이다. 우리가 Main Di..

Language/Kotlin

CoroutineContext와 CoroutineScope 알아보기

이번에는 CoroutineContext는 대체 무엇인지 알아보자. 그리고 간단히 CoroutineScope 구조까지 살펴보도록 하겠다. viewModelScope로 찾아보기viewModelScope는 CoroutineScope라는 인터페이스를 상속받아 만들어진 녀석이다. 그리고 CoroutineScope 인터페이스를 확인해보자.보다시피 CoroutineContext를 가지고 있는 걸 볼 수 있다. 그리고 다시 한 번 CoroutineContext가 무엇인지 들어가보자.문서 최상단을 읽어보면 CoroutineContext는 여러 Context Element를 포함하고 있다는 사실을 알 수 있다. 여기서 가장 중요한 Element에는 바로 Dispatcher, Job, ExceptionHandler, Nam..

Language/Kotlin

Coroutines on Main Thread(위험성에 대해 인지하기)

오늘은 코루틴을 메인 스레드에서 실행해보고 그 결과에 대해 생각해보는 시간을 가져보았다. 어떤 작업을 시킬까이번에는 단순한 연산을 시킬 예정이다. 아주 많이 팩토리얼(Factorial) 계산을 시켜보겠다. 코드를 보자.fun calculateFactorial(number: Int): BigInteger { var factorial = BigInteger.ONE for (i in 1 .. number) { factorial = factorial.multiply(BigInteger.valueOf(i.toLong())) } return factorial}여기서 BigInteger를 사용했는데 간단히 말하면Integer형으로 계산할 때 오버플로우가 날만한 범위까지도 계산이 가능한 클래스이..

Language/Kotlin

Extract retry logic into higher order function from previous Coroutine

이번 글에서는 저번 Coroutine retry 로직을 구현했던 것을 고차함수로 추출해내는 작업을 해볼 예정이다. Step1. 초안 작성하기fun retry(numberOfRetries: Int, block: () -> Unit) { repeat(numberOfRetries) { try { block() } catch (e: Exception) { e.printStackTrace() } } block()}초안을 작성해보면 위와 같은 코드가 된다. 얼핏 보기엔 문제가 없을 것 같지만, 파라미터 전달될 함수 리턴 타입을 알 수 없기에 Unit 하나로 제한해버리면 안된다. 이럴 때 생각나는 녀석이 하나 있는데 바로 제네릭(Generic)이..

Language/Kotlin

Implement Coroutines Retry

이번에는 코루틴으로 재시도하는 동작을 구현해보려한다. 주로 "API 요청을 보내고 정상적인 응답이 오지 않으면 최대 n회 재시도한다" 같은 시나리오에 유용하게 사용할 수 있다. 샘플 코드와 함께 살펴보자. viewModelScope.launch { val retryNumber = 2 try { repeat(retryNumber) { try { loadRecentVersion() return@launch } catch (e: Exception) { e.printStackTrace() } } loadRecentVersion() } c..

Language/Kotlin

Implement Coroutines Timeout

이번에는 코루틴에서 타임아웃 기능을 구현해보자. 너무 뜬금없이 타임아웃 얘기를 해서 살짝 첨언해보자면,API request를 보내고 response에 기본 타임아웃이 있듯 타임아웃을 만들어보자는 것이다. 따라서 내가 소개할 메소드는 withTimeout, withTimeoutOrNull 총 2가지이다. 가장 큰 차이는 예외 발생 여부이다.(여기서 말하는 예외는 TimeoutCancellationException으로 기타 다른 예외들은 당연히 발생할 수 있다.) 코드와 함께 살펴보도록 하자. withTimeoutfun main() = runBlocking { try { withTimeout(1000L) { // some behaviors } } catch(e: TimeoutCance..

Language/Kotlin

async CoroutineBuilder Introduction

이번 글에서는 저번 글에서 빼먹었던 async 코루틴 빌더의 필요성과 어떤 녀석인지 소개해보려고 한다. async CoroutineBuilder 필요성 이해하기대체 이 async라는 코루틴 빌더가 존재하는 이유가 뭘까? 이 빌더를 설명하는 글을 보면 대부분 "결과를 반환받는다" 또는 "실행이 완료되기를 기다릴 수 있다"는 멘트가 적혀있다. 나같은 초급 개발자는 "그게 그렇게 다른점인가?"하고 생각할 수 있다. 뭐 결과를 반환받는 것은 다른 점일 수 있지만,실행이 완료되기를 기다리는 건 launch 코루틴 빌더로도 join() 메소드를 사용하면 가능하기 때문이다. 코드로 launch와 비교해보기어떤 MutableList 원소를 채워넣는 상황이라고 가정해보자. 그리고 두 코드 블럭을 비교해보자. 과연 어떤 ..

Language/Kotlin

Coroutines 기본적인 에러 처리하기(feat. try-catch)

나는 지금까지 예제를 사용하면서 네트워크 작업을 예로 들었다. 게다가 해당 작업이 무조건 정상 동작하는 시나리오로만 공부했다. 만약, 네트워크 작업을 수행할 때 HTTP 500번대와 같은 에러가 발생한다면 어떻게 처리해야할까? 이 에러 상황을 처리하지 않고 앱을 실행하게 되면 바로 크래시가 난다. 그럼 어떡함?제목에서 거의 스포가 되었는데, 정말 간단히 처리하는 방법이 하나 있다. try-catch를 사용하는 것이다. fun performNetworkRequest() { viewModelScope.launch { try { val recentVersions = getRecentVersions() } catch (e: Exception) { e.printStack..

Language/Kotlin

Coroutines의 Main safety

이번 글에서는 Coroutines가 어떻게 main-safety하게 동작하는 지에 대해 설명해보려한다. 먼저 안드로이드 ViewModelScope에서 실행되는 코루틴은 기본적으로 main thread에서 실행된다. 이는 매우 합리적인 이유가 있는데 우리는 ViewModel에서 UI 관련 작업을 자주 수행하기 때문이다. 우리가 ViewModel에서 아래와 같은 함수를 실행한다고 가정해보자.fun performNetworkRequest() { viewModelScope.launch { val recentVersions = getVersions() // this is a suspend function }} 이렇게 네트워크 작업을 Retrofit으로 수행할 때, main thread blocking..

Language/Kotlin

Coroutine Builder 이해하기

우리는 지금까지 예제에서 코루틴을 실행할 때 async를 사용해 suspend function을 실행해왔다. 명확히 하자면 이번 제목이 코루틴을 실행하는데 필요한 녀석이다. 그래서 뭐임?Coroutine Builder(코루틴 빌더)는 새로운 코루틴을 만들기 위해 필요한 녀석이다. 총 3가지 빌더가 있고 launch, async, runBlocking이 있다. 먼저 launch를 사용해보려고 한다. launch 사용하기fun main() { launch {}} 단순히 이렇게 사용할 순 없다. launch는 최상위 함수가 아닌 CoroutineScope의 확장함수이기 때문이다. 이렇게 launch를 사용하려면 새로운 CoroutineScope가 필요하다. launch는 대체 어떤 경우에 사용하는 걸까? 코루..

BonusTrack02.dev
'Language/Kotlin' 카테고리의 글 목록