일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- hotStream
- monotone stack
- coroutine
- Flow
- ShapeableImageView
- coroutinescope
- Advanced LCA
- google play console
- collectLatest
- coroutinecontext
- 백준
- Kotlin
- Next Challenge
- java
- Algorithm
- 백준2309
- flowon
- withContext
- ServerDrivenUI
- 릴리즈 키해시
- TOSS 과제
- KAKAO
- SDUI
- cancellationException
- conflate
- Product Flavor
- 안드로이드
- Android
- app-distribution
- coldStream
- Today
- Total
목록Coroutine (13)
루피도 코딩한다
1. 국룰 try/catch 아래 예시처럼 emitter에서 발생한 Excpetion, 그리고 collecter 에서 발생한 Excpetion 둘 다 try/Catch를 통해 잡을 수 있다. fun exceptionExample(): Flow = flow { for (i in 1..3) { println("Emitting $i") emit(i) // emit next value } }.map { value -> check(value println(value) check(value.contains("1")) { "Collected $value" } ✅ } } catch (e: Throwable) { println("Caught $e") } } 2. Exception transparency (함수형으로 ca..
1. Composing multiple flows (여러개 flow 결합하기) collect 이전에 연산자가 위치하게 된다 Zip : 두개의 flow를 순차적으로 결합 val flow = flowOf(1, 2, 3).onEach { delay(10) } val flow2 = flowOf("a", "b", "c", "d").onEach { delay(15) } flow.zip(flow2) { i, s -> i.toString() + s }.collect { println(it) // Will print "1a 2b 3c" } Combine : 방출되는게 생길때마다 두개의 flow (combine 블록 내부에서 emit하려고 하면 에러남) val flow = flowOf(1, 2).onEach { delay..

지난 포스트에서는 Flow를 방출하는 쪽에서 flowOn연산자를 사용해 Context를 변경하는 방법에 대해 살펴보았다. 이렇게 Producer의 Context를 변경하게 될 경우 오래 걸리는 작업들을 비동기적으로 처리할 수 있어서 도움이 된다. 그러나 만약 Collect 하는 쪽의 작업이 오래 걸리면 어떻게 해야 할까? 방출되는 속도에 비해 처리되는 속도가 현저히 느리며 데이터가 계속 쌓이게 되는 문제를 Back Pressure라고 한다. 이번 포스트는 이런 문제를 해결할 수 있는 Buffering에 대한 내용을 다룬다. 아래 예시를 통해 Collector의 시간이 긴 상황을 살펴보자. emit : 100ms의 delay 걸림 collect : 300ms의 delay 걸림 둘 다 thread를 지정하지..

Flow에서 Context는 두 가지 관점에서 볼 수 있다. 1) 데이터를 Collect 하는 부분의 Contex와, 2) Emit하는 부분의 Context이다. 1. Consumer의 Context 일반적으로 Collect 되는 부분의 Context는 코루틴이 호출된 곳의 Context를 따른다. 아래와 같이 withContext를 활용해 어떤 Dispatcher를 활용해 데이터를 collect 할지 개발자가 지정할 수 있다. Flow의 이러한 성질을 context preservation(콘텍스트 보존)이라 한다. fun main() = runBlocking { withContext(context) { ✅ simple().collect { value -> println(value) // run in t..

Intermediate flow operators Basic Operators map : map 내부에서 변경한 데이터를 downStream으로 흘려보냄 filter : 조건에 맞는 것만 남기기 (조건을 술어 혹은 predicate라고 한다) filterNot : 조건에 맞지 않는것만 남기기 Transform Operator transform : stream 수정 (임의의 값을 임의의 횟수만큼 emit 가능) Size-limiting Operators take(n) : 시작지점부터 n개만큼 data를 다 받아들이면 flow 실행 cancle 시키기 takeWhile : 특정 조건을 만족하는 동안만 값을 가져오게 하기. 조건 안맞으면 즉시 실행 취소 drop(n) : 시작부터 n 개만큼 data 버리기 만..

1. 기본 개념 Flow는 코틀린에서 쓸 수 있는 비동기 '스트림'이다. stream으로 지속적으로 값을 받아들이는 flow는 suspend functions에서 단일 값을 리턴 받는 형식과 반대되는 개념이라고 할 수 있다. Steam에는 3가지 객체가 존재한다. Producer : stream에 data를 흘려보내는 객체이다. 코루틴을 활용해 비동기적으로 데이터를 방출 가능하다. Intermediaries : 있을수도 없을 수도 있다. 필요한 경우에 방출되는 데이터를 가공하는 역할이다 Consumer : Steam으로 부터 data를 소비(consume)하는 객체이다. Android에서 일반적으로 repository가 producer의 역할이고, 데이터를 활용해 화면을 구성하는 UI가 Consumer의..
Suspend함수는 Suspend함수 내부에서 호출 가능하다. delay() 또한 suspend 함수의 일종이다. 아래 코드에는 suspend라는 키워드가 명시적으로 사용되고 있지 않은데 어떻게 delay()를 활용할 수 있을까? fun main(): Unit = runBlocking { launch { delay(100L) } } 그 이유는 runBlocking에 있다. 지난 포스트에서도 한번 봤었지만 다시 runBlocking 함수의 내부 구조를 살펴보도록 하자! Builders.kt 내부 public actual fun runBlocking( context: CoroutineContext, block: suspend CoroutineScope.() -> T) : T { ...} 여기서 block 부..
1. Structured Concorrency Coroutine은 비동기 작업을 효과적으로 다루기 위해 사용되는데, 이를 구조화된(concurrent) 방식으로 관리하는 것이 중요하다. 이전 포스트에서 Coroutine Job의 Life Cycle에 대해 살펴보았다. Life Cycle 값들을 살펴보면 Completed 전에 Completing 상태를 거치는것을 확인할 수 있다. Completing 상태에서 해당 코루틴은 자식 코루틴의 상태를 처리한다. 자식 코루틴이 모두 완료될 때까지 기다리거나, 자식 코루틴에서 예외가 발생한 경우 다른 자식들에게 취소 요청을 보내는 등의 작업을 한다. wait children +-----+ start +--------+ complete +-------------+ f..
이전 글에서 CancellationException()을 통해 코루틴을 취소하는 방법에 대해 알아보았다. 그러면 코루틴에서 예외가 발생할 때 무슨일이 벌어지고, 어떻게 예외처리를 해야할까? 코루틴에서는 예외가 발생하면 '부모 코루틴'에게 예외가 전파된다. 따라서 첫번째로 코루틴의 계층 관계에 대해 정리해보도록 하자! fun main(): Unit = runBlocking { val job1 = launch { delay(1_000L) printWithThread("Job 1") } val job2 = launch { delay(1_000L) printWithThread("Job 2") } } 위 코드의 경우 runBlocking이라는 최상위(aka. root) 코루틴에 launch로 만들어..
코루틴 취소를 왜하냐? 필요하지 않은 코루틴을 적절히 취소해 컴퓨터 자원을 아낄 수 있다 코루틴 취소 하는 방법 == CancellationException 발생 Kotlin 공식문서의 말을 빌리자면 *' A coroutine code has to cooperate to be cancellable' *라고 한다. Cancellable 하다라는 것은 코루틴 블록 내부에서 CancellationException 이 발생가능한 구조여야 한다는 것이다. CancellationException이 발생되는 방법은 아래와 같이 두가지가 있다. [취소 방법 1] kotlinx.coroutines의 suspending function을 활용하자 kotlinx.coroutines의 suspending 함수들은 'cance..